The condition (if it's an expression) of an if
statement is contextually converted to bool
:
[stmt.select]/4 about the condition in selection statements (if
, switch
):
The value of a condition that is an expression is the value of the expression, contextually converted to
bool
for statements other thanswitch
; if that conversion is ill-formed, the program is ill-formed.
Contextual conversion to bool
is defined as follows in [conv]/3:
An expression
e
can be implicitly converted to a typeT
if and only if the declarationT t=e;
is well-formed, for some invented temporary variablet
. Certain language constructs require that an expression be converted to a Boolean value. An expressione
appearing in such a context is said to be contextually converted tobool
and is well-formed if and only if the declarationbool t(e);
is well-formed, for some invented temporary variablet
.
Here's the description of a conversion to bool
for fundamental types [conv.bool]/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 tofalse
; any other value is converted totrue
. A prvalue of typestd::nullptr_t
can be converted to a prvalue of typebool
; the resulting value isfalse
.
So when we test a pointer if(ptr)
, we compare ptr
to the null pointer value of that type. What's a null pointer value? [conv.ptr]/1
A null pointer constant is an integral constant expression prvalue of integer type that evaluates to zero or a prvalue of type
std::nullptr_t
. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type. Such a conversion is called a null pointer conversion. Two null pointer values of the same type shall compare equal.
This also describes what happens when we compare if(ptr != nullptr)
: The nullptr
is converted to the type of ptr
(see [expr.rel]/2), and yields the null pointer value of that type. Hence, the comparison is equivalent to if(ptr)
.