Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is nullptr falsy?

Tags:

When used as a boolean expression or transformed into a boolean either explicitly or implicitly, is nullptr consistently false? Is this implementation defined or specified in the standard?

I wrote some code to test, but am not certain if it tests this property fully. I couldn't find an existing SO answer that talked specifically about this. cppreference doesn't mention this from what I see.

if (nullptr) {     ; } else {     std::cout << "Evaluates to false implicitly\n"; }  if (!nullptr) {     std::cout << "Evaluates to false if operated on\n"; }  if (!(bool)(nullptr)) {     std::cout << "Evaluates to false if explicitly cast to bool\n"; } 

Expected and actual:

Evaluates to false implicitly Evaluates to false if operated on Evaluates to false if explicitly cast to bool 
like image 540
David Thompson Avatar asked Aug 16 '19 15:08

David Thompson


People also ask

Is nullptr a Falsy in C++?

2.4, new clause) 1 The type nullptr_t may be converted to bool or to a pointer type. The result is false or a null pointer value, respectively.

What does nullptr equal to?

nullptr vs NULL NULL is 0(zero) i.e. integer constant zero with C-style typecast to void*, while nullptr is prvalue of type nullptr_t which is integer literal evaluates to zero.

Is nullptr == null?

nullptr is a keyword that can be used at all places where NULL is expected. Like NULL, nullptr is implicitly convertible and comparable to any pointer type. Unlike NULL, it is not implicitly convertible or comparable to integral types.

Is nullptr always false?

Comparing any variable with NULL will always evaluate to FALSE, regardless if it's value, unless IS NULL or IS NOT NULL is used. Violating this rule will affect the functionality of the code. The severity is critical which means that the code will not function correctly.


2 Answers

According to the C++ 17 Standard (5.13.7 Pointer literals)

1 The pointer literal is the keyword nullptr. It is a prvalue of type std::nullptr_t. [ Note: std::nullptr_t is a distinct type that is neither a pointer type nor a pointer-to-member type; rather, a prvalue of this type is a null pointer constant and can be converted to a null pointer value or null member pointer value. See 7.11 and 7.12. — end note ]

And (7 Standard conversions)

4 Certain language constructs require that an expression be converted to a Boolean value. An expression e appearing in such a context is said to be contextually converted to bool and is well-formed if and only if the declaration bool t(e); is well-formed, for some invented temporary variable t (11.6).

And at last (7.14 Boolean conversions)

1 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. For direct-initialization (11.6), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.

That is you may write for example

bool b( nullptr ); 

but you may not write (though some compilers have a bug relative to this)

bool b = nullptr; 

So nullptr can be contextually converted to an object of the type bool for example in selection statements like the if-statement.

Let's consider for example the unary operator ! as in an if statement

if ( !nullptr ) { /*...*/ } 

According to the description of the operator (8.5.2.1 Unary operators)

9 The operand of the logical negation operator ! is contextually converted to bool (Clause 7); its value is true if the converted operand is false and false otherwise. The type of the result is bool

So nullptr in this expression is not converted to a pointer. It is directly contextually converted to bool.

like image 94
Vlad from Moscow Avatar answered Oct 18 '22 21:10

Vlad from Moscow


The result of your code is guaranteed, [dcl.init]/17.8

Otherwise, if the initialization is direct-initialization, the source type is std​::​nullptr_­t, and the destination type is bool, the initial value of the object being initialized is false.

That means, for direct-initialization, a bool object may be initialized from nullptr, with the result value false. Then for (bool)(nullptr), nullptr is converted to bool with value false.

When using nullptr as condition of if or the operand of operator!, it's considered as contextual conversions,

the implicit conversion is performed if the declaration bool t(e); is well-formed

That means, both if (nullptr) and !nullptr, nullptr will be converted to bool with value false.

like image 43
songyuanyao Avatar answered Oct 18 '22 22:10

songyuanyao