songyuanyao
songyuanyao

Reputation: 172984

When using typeid on a polymorphic object, must it be defined?

When using typeid on a polymorphic object, I think the object must be defined (not just a declaration) because typeid operation needs to get the object's information at runtime. Here's my code:

#include <iostream>
#include <typeinfo>

class D {
    virtual ~D() {}
};
extern D d;

int main()
{
    std::cout << typeid(d).name() << std::endl;
    std::cout << sizeof(d) << std::endl;
}

And with clang 3.4, I got the link error:

undefined reference to `d'

But with g++ 4.8.1, it works well and I got the result:

1D
8

My question:

  1. Which one is right?
  2. How does g++ implement typeid? How can it get the information from a polymorphic object without definition?

Upvotes: 7

Views: 1102

Answers (1)

R Sahu
R Sahu

Reputation: 206697

From http://en.cppreference.com/w/cpp/language/typeid

a) If expression is a glvalue expression that identifies an object of a polymorphic type (that is, a class that declares or inherits at least one virtual function), the typeid expression evaluates the expression and then refers to the std::type_info object that represents the dynamic type of the expression. If the result of the evaluated expression is a null pointer, an exception of type std::bad_typeid or a type derived from std::bad_typeid is thrown.

Sounds like clang 3.4 is right.

Update

The standard says:

When typeid is applied to a glvalue expression whose type is a polymorphic class type (10.3), the result refers to a std::type_info object representing the type of the most derived object (1.8) (that is, the dynamic type) to which the glvalue refers. If the glvalue expression is obtained by applying the unary * operator to a pointer and the pointer is a null pointer value (4.10), the typeid expression throws the std::bad_typeid exception (18.7.3).

It is slightly different from the language used by cppreference.com but it still points to clang 3.4 being right.

Upvotes: 2

Related Questions