Search code examples
c++c++11language-lawyerimplicit-conversionnullptr

Is nullptr falsy?


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

Solution

  • 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.