14

Here is a declaration of nullptr_t in <cstddef> :

namespace std {
  typedef decltype(nullptr) nullptr_t;
}

According to this, std::nullptr_t is an alias for some unspecified fundamental type of which nullptr is an instance. So the actual type of nullptr doesn't have a name (well, the language does not give it a name, the name was given by standard library).

nullptr itself is a keyword. But standard did not introduce a keyword for type of nullptr. Instead using decltype(nullptr) is offered.

What are reasons for doing this? I found it much confusing. You need to include header and specify std:: for just using a language built-in feature.

Is this to keep the set of C++ keywords as small as possible? Is this specifically for nullptr or committee is going to declare all new types like this, so we would have namespace std { typedef decltype(false) bool; } if such decision was made earlier?

anton_rh
  • 8,226
  • 7
  • 45
  • 73
  • 2
    Yes, nothing breaks existing code worse than adding new keywords to a language. Contextual keywords like `enum class`, `final`, `override` are a decent alternative btw. – Hans Passant Dec 05 '15 at 16:06
  • But it's also the easiest thing to detect and fix (of course there are always pathological cases, e.g. code generation). Cosidering this, there are probably a myriad worse ways to break existing code. – Karoly Horvath Dec 05 '15 at 16:14
  • Adding new keywords introduces potential breaks for existing code which the committee tries to avoid if possible. See [Why are override and final identifiers with special meaning instead of reserved keywords?](http://stackoverflow.com/q/30404388/1708801) for the rationale for not making override and final reserved words. – Shafik Yaghmour Dec 05 '15 at 17:46

3 Answers3

11

According to the initial proposal of nullptr, N2431 (Emphasis Mine):

We propose a new standard reserved word nullptr. The nullptr keyword designates a constant rvalue of type decltype(nullptr). We also provide the typedef: typedef decltype(nullptr) nullptr_t; nullptr_t is not a reserved word. It is a typedef (as its _t typedef indicates) for decltype(nullptr) defined in <cstddef>. We do not expect to see much direct use of nullptr_t in real programs.

Generally, the committee is reluctant in the addition of new keywords in the language. In my humble opinion this is for a good reason, named backward compatibility.

If you further read the proposal, you'd realize that the main concern is not breaking existing code.

Imagine the effect that would have if the committee now and then introduced a new keyword. All hell would break loose and C++ from a success story would have been a big joke.

101010
  • 41,839
  • 11
  • 94
  • 168
  • 3
    However new keyword for `nullptr` was added. I'm sure it has higher chances that someone already used `nullptr` in their code than used `nullptr_t` because "We do not expect to see much direct use of nullptr_t in real programs." – anton_rh Dec 05 '15 at 16:43
  • so new types are expected to be added to `std` namespace? – anton_rh Dec 05 '15 at 16:44
  • @anton_rh They proposed `nullptr` to be a keyword. "We propose a new standard reserved word nullptr.". The name was chosen after an informal pole and google search. – 101010 Dec 05 '15 at 16:48
  • 2
    @anton_rh Trust the committee they're wise. They have to consider things that we are not aware of and make the best compromise out of them. – 101010 Dec 05 '15 at 16:50
3

I believe the reason is simple: the standardization committee wants to avoid as much as reasonably possible to introduce new keywords (because, given the billions lines of existing C++ code, it is likely to conflict with some code somewhere).

Since std::nullptr_t is definable, it does not need to be a keyword.

And bool is a keyword for historical reasons. It very probably has been introduced quite early...

C++ is mostly about legacy software, so human and social and economical considerations (and backward compatibility) matters a lot for the standardization committee (often more than technical reasons alone).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 3
    we can avoid using keywords at all. Just use `std::` for everything. `std::int int = 10, while = 0; std::while(int > while) ...` – anton_rh Dec 05 '15 at 16:08
  • 1
    But the C++ committee did not want that. FWIW PL/1 is a language without keywords, so `IF IF=THEN THEN ELSE=IF;` is valid in PL/1 but unreadable – Basile Starynkevitch Dec 05 '15 at 16:45
3

Adding new keywords are avoided when not necessary. Why add something to the language when it can just be added to the library.

You already have a similar thing with sizeof(x) which returns std::size_t, which you also have to include a header to get the typedef for.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • I thought that `size_t` is just a typedef to `unsigned int` or something else that is correct for the platform running code. No built-in features here. – anton_rh Dec 05 '15 at 16:19
  • @anton - Yes, `std::size_t` is a typedef, just like `std::nullptr_t`. :-) And the compiler can return a value of that type for `sizeof`, just like it can return a value for `nullptr`, even if none of the typedefs are visible. No difference! – Bo Persson Dec 05 '15 at 16:24
  • I was sure that *size_t* is mapped to existing *named* type (like _unsigned int_). That is difference. Though can't find it in `stddef.h` and become thinking it's magic too... O_o – anton_rh Dec 05 '15 at 16:36
  • Found a good thread that exposes analogy between std::nullptr_t and std::size_t: http://stackoverflow.com/a/20809166/5447906 – anton_rh Dec 05 '15 at 17:18