Raphael Lopes
Raphael Lopes

Reputation: 153

Undefined Reference to "typeinfo for <class>"

I saw questions about this problem but i can't find any solutions working for me. I am using Visual Code with C++ and C++ version is anterior to C++ 11. I have DNS classes, with various classes inheriting a principal DNS message class, this way I can factorize some attributes. In function of the type type field I can know the type of the object. When I compile I have an error "undefined reference to "typeinfo for DNS_RR_A" for example, but I got this at each dynamic cast I am doing to check the class of the object.

My dnsMessage.cpp only have constructor and destructor.

here is my classes:

class CDnsMessage
{       
    public:
        CDnsMessage();
        virtual ~CDnsMessage();

        virtual void GetSize() = 0;

        uint32_t       m_ttl;
        eDnsClass      m_class;
        eDnsType       m_type; 
        std::string    m_domain; 
        uint8_t        m_sizeDnsCorpse;
        uint8_t        m_sizeDomainName; 
};

class CDns_RR_A : public CDnsMessage
{
    public:
        CDns_RR_A();
        virtual ~CDns_RR_A();

        virtual void GetSize() {/*....*/}

        uint32_t        m_address;
};

And here is a sample of my function using with the error at the dynamic cast. I receive a message I have to encode but I don't know the nature of the message so I dynamic cast so I can adapt my encode:

//i receive a message i have to encode, i don't know the type 
void EncodeOpaqueData(CDnsMessage & msg, std::vector<uint8_t>& output)
{
//where i encode
    output.clear();

    // Error : "undefined reference to `typeinfo for CDns_RR_A'"
    if(dynamic_cast< CDns_RR_A* >( &msg ) != NULL) 
    {       
            CDns_RR_A* RR_A_msg = dynamic_cast< CDns_RR_A* >( &msg );

            uint16_t dnstype = cmn_hton16(1);
            output.push_back(dnstype);
            output.push_back(dnstype >> 8);
            /* stuff here */

            uint32_t address = cmn_hton32(RR_A_msg->m_address);
            for (int i = 0; i < 4; i++)
            {
                    output.push_back(static_cast<uint8_t>(address >>(i * 8)));
            }

    }
}

After think more of the function, instead of checking the type of the object I could check msg->m_type and adapt in function of the type, the m_type variable can be wrongly instantiated for example. But anyway I would like to understand this error and how to fix it. thanks in advance.

Upvotes: 2

Views: 6111

Answers (2)

Jan Hudec
Jan Hudec

Reputation: 76346

The class impedimenta—virtual method table and typeinfo—are generated when the first declared virtual method is compiled. Are you defining the virtual ~CDnsMessage(); (i.e. CDnsMessage::~CDnsMessage() {}) and is the file where it is defined included in the link.

Note that out-of-line definitions are not weak, so it must be defined in exactly one source (not header) file.

Upvotes: 3

SuperG280
SuperG280

Reputation: 271

Try to change the reference parameter to a pointer like this:

void EncodeOpaqueData(CDnsMessage * msg, std::vector<uint8_t>& output)

You have the explanation here:

Difference in behavior while using dynamic_cast with reference and pointers

Upvotes: 2

Related Questions