16

The typeid represents a C++ RTTI operator being also a C++ keyword. It returns a std::type_info object that holds (dynamic) type specific information.

From what I understood from various sources, one MUST include <typeinfo> when using typeid, otherwise the program is ill-formed. In fact, my gcc5.2 compiler doesn't even compile the program if I don't include the before-mentioned header. I don't understand why is a header inclusion mandated for the usage of a C++ keyword. I understand mandating a header for whenever we use some object declared/defined in that header, but typeid is not of a class type. So what is the reason behind this enforcement of including the header <typeinfo>?

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • 4
    For something similar, `` also needs to be included in cases you may or may not expect. – chris Nov 14 '15 at 04:13
  • @chris I think only when you explicitly use `std::initializer_list`, which makes a bit more sense, since `std::initializer_list` is a class of its own, not a keyword, although implicitly used by the core language. – vsoftco Nov 14 '15 at 04:15
  • 1
    Yes, though there are some trickier cases such as `auto list = {1, 2, 3};` and `for (auto x : {1, 2, 3}) {}`. – chris Nov 14 '15 at 04:22
  • @chris Yes, but do you have to include the header in the case you just mentioned? From what I know, the type is deduced as `initializer_list` without the need to include the header. Which is more weird in a sense, since `list` is now of an object type `std::initializer_list`. Ohh yes, you need to include it... Strange and ugly design imo. – vsoftco Nov 14 '15 at 04:23
  • 1
    Yep, *if the header is not included prior to a use of std::initializer_list — even an implicit use in which the type is not named (7.1.6.4) — the program is ill-formed.* ([dcl.init.list]/2) The link leads to `auto`. As for the second, there's [this question](http://stackoverflow.com/questions/8913701/include-initializer-list-required-to-use-initializer-list-in-range-based-for). – chris Nov 14 '15 at 04:26
  • I think there's a similar rule for `std::nullptr_t` – Ben Voigt Nov 14 '15 at 04:31
  • @BenVoigt, It's interesting for sure. The standard provides an explicit definition for it as something really close to "`std::nullptr_t` shall be defined as: `typedef decltype(nullptr) nullptr_t;`" – chris Nov 14 '15 at 04:47
  • @chris And then: *"nullptr is a prvalue of type std::nullptr_t.* – vsoftco Nov 14 '15 at 04:49
  • The reason is "because so". C++ does not make an effort to properly separate the core language from its standard library. – alecov Jul 18 '16 at 15:22

2 Answers2

11

The next paragraph:

The typeid expression is lvalue expression which refers to an object with static storage duration, of the polymorphic type const std::type_info or of some type derived from it.

Because it is an lvalue expression, which uses reference initialization to declare an initializer of std::type_info. <typeinfo> contains the definition for that object.

mattkgross
  • 791
  • 2
  • 12
  • 24
  • 2
    Probably this is the reason, although I find the design of the language... let's say strange, since it allows a keyword to depend on headers... – vsoftco Nov 14 '15 at 04:26
6

typeid is not the only one that needs header

new also requires header <new> in some cases

Note: the implicit declarations do not introduce the names std, std::bad_alloc, and std::size_t, or any other names that the library uses to declare these names. Thus, a new-expression, delete-expression or function call that refers to one of these functions without including the header is well-formed. However, referring to std, std::bad_alloc, and std::size_t is ill-formed unless the name has been declared by including the appropriate header. —end note

See abhay's answer on new keyword

Another operator sizeof which returns std::size_t ( It does not actually need to include header, but my point here is that it uses an alias which is also defined in a header)

C++ §5.3.3

The result of sizeof and sizeof... is a constant of type std::size_t. [Note: std::size_t is defined in the standard header <cstddef>(18.2).— end note]

typeid use classes which are declared in <typeinfo> header

Header <typeinfo> synopsis

namespace std {
class type_info;
class bad_cast;
class bad_typeid;
}

See section 18.7 on iso cpp paper

IMO, Its C++ Standard Design Techniques, to keep the compiler neat, clean and lightweight

Community
  • 1
  • 1
Abdul Rehman
  • 1,687
  • 18
  • 31
  • 2
    size_t is a type alias, so you don't need to include the header to use the result of sizeof though – vsoftco Nov 14 '15 at 06:11
  • @AbdulRehman saying "typeid is not the only one that needs header" and then introducing "sizeof" seems like you are saying that sizeof also needs header. – M.M Nov 14 '15 at 06:41
  • `new T` doesn't require ``, only certain uses of `new` do. as explained by your quote. – M.M Nov 14 '15 at 06:42