प्रकार के क्षरण के कारणों में मेरे पास एक A<T> टेम्पलेट है जो किसी भी डेटाटाइप को पकड़ सकता है। जब A एक बहुरूपी प्रकार Derived रखता है, जो Base से प्राप्त होता है और मैंने इसे A<Base> में डाल दिया है, GCC के अपरिभाषित व्यवहार सैनिटाइजर रेंडम त्रुटियों की रिपोर्ट करता है।

#include <iostream>

struct I
{
    virtual ~I() = default;
};

template<typename T> 
struct A : public I
{
    explicit A(T&& value) : value(std::move(value)) {}
    T& get() { return value; }
private:
    T value;
};

struct Base
{
    virtual ~Base() = default;
    virtual void fun() 
    {
        std::cout << "Derived" << std::endl;
    }
};

struct Derived : Base
{
    void fun() override
    {
        std::cout << "Derived" << std::endl;
    }
};

int main()
{
    I* a_holding_derived = new A<Derived>(Derived());
    A<Base>* a_base = static_cast<A<Base>*>(a_holding_derived);
    Base& b = a_base->get();
    b.fun();
    return 0;
}

संकलन & amp; रन

$ g++ -fsanitize=undefined -g -std=c++11 -O0 -fno-omit-frame-pointer && ./a.out

उत्पादन:

main.cpp:37:62: runtime error: downcast of address 0x000001902c20 which does not point to an object of type 'A'

0x000001902c20: note: object is of type 'A<Derived>'

 00 00 00 00  20 1e 40 00 00 00 00 00  40 1e 40 00 00 00 00 00  00 00 00 00 00 00 00 00  21 00 00 00

              ^~~~~~~~~~~~~~~~~~~~~~~

              vptr for 'A<Derived>'

    #0 0x400e96 in main /tmp/1450529422.93451/main.cpp:37

    #1 0x7f35cb1a176c in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)

    #2 0x400be8  (/tmp/1450529422.93451/a.out+0x400be8)


main.cpp:38:27: runtime error: member call on address 0x000001902c20 which does not point to an object of type 'A'

0x000001902c20: note: object is of type 'A<Derived>'

 00 00 00 00  20 1e 40 00 00 00 00 00  40 1e 40 00 00 00 00 00  00 00 00 00 00 00 00 00  21 00 00 00

              ^~~~~~~~~~~~~~~~~~~~~~~

              vptr for 'A<Derived>'

    #0 0x400f5b in main /tmp/1450529422.93451/main.cpp:38

    #1 0x7f35cb1a176c in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)

    #2 0x400be8  (/tmp/1450529422.93451/a.out+0x400be8)


Derived

कॉलिरु पर लाइव उदाहरण / kbd>

मेरे दो सवाल हैं:

  1. सैनिटाइज़र का आउटपुट सही है?
  2. यदि हाँ, तो A<Derived> से A<Base> तक वैध रूपांतरण कैसे दिखेगा?
3
m.s. 19 पद 2015, 16:00

1 उत्तर

सबसे बढ़िया उत्तर

मुद्दा यह है कि A<Base> और A<Derived> का एक-दूसरे से कोई संबंध बिल्कुल नहीं है। उन्हें पूरी तरह से अलग तरीके से पेश किया जा सकता है। जिस कास्ट के लिए आप प्रयास कर रहे हैं, यह आवश्यक होगा कि A<Base> A<Derived> का एक आधार वर्ग है जो स्पष्ट रूप से ऐसा नहीं है।

ऐसा लगता है, आप एक स्मार्ट पॉइंटर की तरह कुछ बनाना चाहते हैं जो मूल्य प्रकार की तरह व्यवहार करता है। ऑफ-हैंड, मुझे यकीन नहीं है कि क्या एक मूल्य प्रकार बनाया जा सकता है जो समर्थित सभी आवश्यक रूपांतरणों का समर्थन करता है। यदि विशिष्ट प्रकार या समूहों के समूहों में एक सामान्य सामान्य वर्ग वर्ग है जिसके लिए रूपांतरणों का समर्थन करने की आवश्यकता होती है, तो इसी वर्ग को लागू किया जा सकता है।

4
Dietmar Kühl 19 पद 2015, 13:20