Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why "bool c = nullptr ;" compiles (C++11)?

I don't understand why following code compiles ?

int main() {      //int a = nullptr;  // Doesn't Compile      //char b = nullptr; // Doesn't Compile        bool c = nullptr; // Compiles         return 0; } 

whereas the commented section doesn't.


I've already gone through this and this.

Both bool and nullptr are keywords, so what's unique about the other data types?

like image 226
P0W Avatar asked Feb 25 '14 11:02

P0W


People also ask

What is nullptr in C++11?

The C++11 standard introduced a new keyword, nullptr as a null pointer constant. The nullptr constant can be distinguished from integer 0 for overloaded functions.

Does nullptr work in C?

nullptr is a new keyword introduced in C++11. nullptr is meant as a replacement to NULL . nullptr provides a typesafe pointer value representing an empty (null) pointer. The general rule of thumb that I recommend is that you should start using nullptr whenever you would have used NULL in the past.

Where is nullptr defined C?

The C standard requires that NULL be defined in locale. h , stddef. h , stdio.

Is nullptr == null?

In C++11 and beyond, a pointer that is ==NULL will also ==nullptr and vice versa. Uses of NULL other than comparing with a pointer (like using it to represent the nul byte at the end of a string) won't work with nullptr .


2 Answers

For the same reason as

if( p ) { ... } 

compiles: any value of basic type converts implicitly to boolean, with 0 converting to false and any other value to true.

Originally basic type values had to convert to bool for C compatibility. C didn't originally have a bool type, but any numerical expression could be used as a boolean (with the 0 == false convention). And now we're caught in the backward compatibility tangle. nullptr has to support idiomatic constructs such as if(p), especially for the cases where old code's literal 0 or NULL is replaced with nullptr. E.g. code like if(p) can result from a macro expansion, or in template code.


Addendum: the technical how of why nullptr doesn't convert to e.g. int.

Since nullptr converts implicitly to bool, and bool (unfortunately) converts implicitly to int, one could expect that nullptr should also convert to int. But the point of nullptr is that it should behave as a pointer value. And while pointers do convert implicitly to bool, they do not convert implicitly to numerical types.

Arranging such a restriction for a user-defined type is however not entirely straightforward. An operator bool conversion will be invoked for conversion to int, if it's present. One C++11 solution to enfore the restriction, is to make the conversion operator a template, restricted by a std::enable_if, as follows:

#include <type_traits>  // std::enable_if, std::is_same  struct S {     template< class Type >     operator Type* () const { return 0; }      template<         class Bool_type,         class Enabled = typename std::enable_if<             std::is_same<Bool_type, bool>::value, void             >::type         >     operator Bool_type () const { return false; } };  auto main() -> int {     bool const              b   = S();      // OK.     double const*  const    p   = S();      // OK.     int const               i   = S();      // !Doesn't compile. } 
like image 185
Cheers and hth. - Alf Avatar answered Sep 22 '22 22:09

Cheers and hth. - Alf


C++11 §4.12 Boolean conversions

A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. A prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.

It's true that nullptr is a keyword, but it's a null pointer literal, not the same role as bool. Think about the boolean literals, true and false are also keywords.

like image 40
Yu Hao Avatar answered Sep 18 '22 22:09

Yu Hao