Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?
like image 227
songyuanyao Avatar asked Jun 18 '14 05:06

songyuanyao


People also ask

What is the use of Typeid () function?

The typeid operator allows the type of an object to be determined at run time. The result of typeid is a const type_info& . The value is a reference to a type_info object that represents either the type-id or the type of the expression, depending on which form of typeid is used.

How does Typeid work in C++?

The typeid operator is used to determine the class of an object at runtime. It returns a reference to a std::type_info object, which exists until the end of the program, that describes the "object". If the "object" is a dereferenced null pointer, then the operation will throw a std::bad_typeid exception.

Does Typeid require RTTI?

The typeid operator requires RunTime Type Identification (RTTI) to be generated, which must be explicitly specified at compile time through a compiler option.

Is Typeid a keyword in C++?

typeid is an operator in C++. It is used where the dynamic type or runtime type information of an object is needed. It is included in the <typeinfo> library. Hence inorder to use typeid, this library should be included in the program.


1 Answers

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.

like image 66
R Sahu Avatar answered Sep 29 '22 08:09

R Sahu