Document number:  N2656=08-0166
Date:  2008-06-10
Author:  J. Stephen Adamczyk, Edison Design Group
 jsa@edg.com

Core issue 654 wording

Core issue 654 recommends three additions to the nullptr functionality:

  • An integral zero constant should be convertible to nullptr_t.
  • A nullptr_t value should be convertible to bool, but only in the "contextually converted to bool" contexts.
  • A nullptr_t value should be convertible to an integral type via a reinterpret_cast.
  • In discussion of the second bullet in the CWG on June 9, we decided that consistency between pointers and nullptr_t was desirable, i.e., a nullptr_t value should be convertible to bool in exactly the same contexts that a pointer is convertible to bool. There was some disagreement over whether this should be all contexts (as is true for pointers in the current standard), or whether it should be only the "contextually converted to bool" contexts (which, for pointer cases, would require breaking some code that is currently valid). We are going forward with allowing the conversions in all contexts, and we have asked implementers to try the breaking change for pointers and report back on the effect on existing code bases. If the change seems harmless (or beneficial), we may produce a separate proposal at the next meeting to limit conversions of both nullptr_t and pointers to bool to the "contextually converted to bool" (really, direct-initialization) contexts.

    Working Draft changes

    Change 4.10 [conv.ptr] paragraph 1 as follows:

    A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero or an rvalue 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 pointer to object or pointer to function type. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion (4.4). A null pointer constant of integral type can be converted to an rvalue of type std::nullptr_t. [Note: The resulting rvalue is not a null pointer value.]

    [Drafting note: It wasn't clear before whether a nullptr_t rvalue is a null pointer value. I have made it clear it isn't, on the logic that it's not a pointer; it could equally be considered a null pointer to member. I checked the uses of "null pointer value," and saw no cases where this would be a problem.]

    Change 4.12 [conv.bool] paragraph 1 as follows:

    An rvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to an rvalue 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. An rvalue of type std::nullptr_t can be converted to an rvalue of type bool; the resulting value is false.

    [Drafting note: Note the en passant addition of a missing semicolon.]

    Changes 5.2.10 [expr.reinterpret.cast] paragraphs 4 and 9 as follows:

    A pointer can be explicitly converted to any integral type large enough to hold it. The mapping function is implementation-defined. [ Note: it is intended to be unsurprising to those who know the addressing structure of the underlying machine. --end note ] A value of type std::nullptr_t can be explicitly converted to an integral type; the conversion has the same meaning and validity as a conversion of (void *)0 to the integral type. [ Note: a reinterpret_cast cannot be used to convert a value of any type to the type std::nullptr_t. --end note ]
    ...
    The null pointer value (4.10) is converted to the null pointer value of the destination type. [ Note: A null pointer constant of integral type is not necessarily converted to a null pointer value. (A null pointer constant of type std::nullptr_t cannot appear as the operand of reinterpret_cast, nor can any value be converted by reinterpret_cast to type std::nullptr_t.) A null pointer constant of type std::nullptr_t cannot be converted to a pointer type, and a null pointer constant of integral type is not necessarily converted to a null pointer value. --end note ]

    [Drafting note: 13.3.3.1.1 [over.best.ics] table 11 covers the cost of standard conversions and does not need to be updated for this change. Because of the sections in which they are defined (4.10 and 4.12), 0 converted to nullptr_t is a pointer conversion, and nullptr_t converted to bool is a boolean conversion, and they get the appropriate cost in overload resolution.]

    End of document.