3

Consider following example:

#include <iostream>
#include <typeinfo>
int main()
{
    int a=9;
    std::cout << typeid(a).name() << '\n';
}

Output on g++ 4.8.1 : i

Output on MSVS 2010: int

Why output is compiler depedent? What is the reason behind this? Why it is left as implementation defined? Why not same output on all compilers? Does C++ standard says it explicitly?

Destructor
  • 14,123
  • 11
  • 61
  • 126
  • related: http://stackoverflow.com/questions/4465872/why-does-typeid-name-return-weird-characters-using-gcc-and-how-to-make-it-prin – Class Skeleton Sep 02 '15 at 13:38

5 Answers5

6

Because compilers represent types differently and don't use the same internals.

The G++ string is the mangled type name, returning that (rather than demangling it) is less work and more efficient. Requiring compilers to demangle those strings would add more work. The standard leaves it up to implementors to decide if they want to do that.

If the standard dictated it then it would also have to specify all sorts of things, like whether to say signed long or just long and how to represent complex template instantiations that depend on other types and constants. The benefits of standardising those strings would be very small, but a large amount of work.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
2

Yes, C++ standard says it explicitly:

18.7.1$9,10 Class type_info [type.info]

const char* name() const noexcept; 

9 Returns: An implementation-defined ntbs.
10 Remarks: The message may be a null-terminated multibyte string (17.5.2.1.4.2), suitable for conversion and display as a wstring (21.3, 22.4.1.4)

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
1

The C++ standard says:

The class type_info describes type information generated by the implementation. Objects of this class effectively store a pointer to a name for the type, and an encoded value suitable for comparing two types for equality or collating order. The names, encoding rule, and collating sequence for types are all unspecified and may differ between programs.

g++ is returning you the decorated name which you can demangle easily.

Also refer: Print variable type in C++

Community
  • 1
  • 1
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • This seems to be add odds with the accepted answer: _unspecified_ and _implementation-defined_ are two distinct kinds of behavior. Can you indicate which part of which standard this quote comes from? – MSalters Dec 02 '16 at 12:30
0

To expand on Jonathan Wakely's answer, the typical use of typeid is

if ( typeid(variable1) == typeid(variable2) )
     // same type

but also

if ( typeid(variable1).name() == typeid(variable2).name() )
    // same type

as you can see there is no need to know the exact implementation-defined name. Since you don't really need that, the standard gives the implementation freedom to implement it in a more efficient way, which is reasonably good.

For example, compare _ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_ and std::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) : definitely less verbose and efficient, to compare and to store.

edmz
  • 8,220
  • 2
  • 26
  • 45
0

In addition typeid is mainly used with polymorphic types to detect polymorphic object types at runtime:

#include <iostream>
#include <typeinfo>

class B
{
public:
    virtual ~B() {}
};

class D1 : public B
{

};

class D2 : public D1
{

};

int main()
{
    B* b1 = new D2;
    if (typeid(*b1) == typeid(B))
    {
        std::cout << "*b1 is B\n";
    }
    if (typeid(*b1) == typeid(D1))
    {
        std::cout << "*b1 is D1\n";
    }
    if (typeid(*b1) == typeid(D2))
    {
        std::cout << "*b1 is D2\n";
    }
}

This will print

*b1 is D2

So it is not intended for printing names of object types.

Hrant
  • 496
  • 1
  • 5
  • 13