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 than switch
; 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 type T
if and only if the declaration T t=e;
is well-formed, for some invented temporary variable t
. 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
.
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 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
.
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)
.