I can't tell from the C++11 Standard if nullptr_t has a default constructor. In other words, is the following valid?:
nullptr_t n;
GCC and VC++ allow the above code, but clang does not. I can't find anything in the Standard specifying that it doesn't have a default constructor, and what I can find suggests that it ought to. This matters to me because I'm writing a basic fallback implementation of nullptr for older compiler support and need to know if I need to give it a default constructor.
N@G3 " [...] a variable or pointer is given a null "value" by default [...] " Pointers have no specific default value.
The Standard states, that nullptr is a pointer literal of type std::nullptr_t (2.14.7).
(since C++11) std::nullptr_t is the type of the null pointer literal, nullptr. It is a distinct type that is not itself a pointer type or a pointer to member type. Its values are null pointer constants (see NULL), and may be implicitly converted to any pointer and pointer to member type.
The standard says (18.2)
nullptr_t is defined as follows:
namespace std { typedef decltype(nullptr) nullptr_t; }
The type for which nullptr_t is a synonym has the characteristics described in 3.9.1 and 4.10.
Where 3.9.1 basically says it should be of the same size as void*
and 4.10 specifies the conversion rules for nullptr
.
Edit: 3.9.9 furthermore explicitly states that nullptr_t
is a scalar type, which means the expected initialization rules for built-in types from 8.5 apply:
nullptr_t n;
), which leaves the value of n
undefined. As Johannes Schaub pointed out correctly, this compiles fine with the newest version of Clang.nullptr_t n = nullptr_t();
), which initializes n to 0.This behavior is identical to e.g. int
, so nullptr_t
is definitely default-constructible.
The interesting question here is: What does it mean for nullptr_t
to have undefined value? At the end of the day, there is only one meaningful possible value for nullptr_t
, which is nullptr
. Furthermore the type itself is only defined through the semantics of the nullptr
literal. Do these semantics still apply for an unitialized value?
You don't want to declare a new variable of type nullptr_t
. The only meaningful semantic of that type is already expressed through the nullptr
literal, so whenever you would use your custom variable of type nullptr_t
, you can just as well use nullptr
.
The only exception to this comes from the fact that you can take non-type template parameters of type nullptr_t
. For this case, it is useful to know which values can convert to nullptr_t
, which is described in 4.10:
A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type
std::nullptr_t
. [...] A null pointer constant of integral type can be converted to a prvalue of typestd::nullptr_t
.
Which basically does just what you'd expect: You can write
nullptr_t n = 0; // correct: 0 is special
but not
nullptr_t n = 42; // WRONG can't convert int to nullptr_t
Both gcc 4.6 and Clang SVN get this right.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With