Consider the following C++11 program, and its result in GCC 4.7.2:
int main()
{
constexpr int i = 0;
int* p = i;
}
// g++ -g -ggdb -Wall -Wextra -pedantic -std=c++11 t.cpp
// t.cpp: In function 'int main()':
// t.cpp:4:13: error: invalid conversion from 'int' to 'int*' [-fpermissive]
// t.cpp:4:9: warning: unused variable 'p' [-Wunused-variable]
According to the standard:
[C++11: 4.10/1]:A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero [..]
5.19 is a mess and I've failed to parse it fully, but wouldn't we expect i to satisfy this criterion and act as a null pointer constant, consequently requiring no explicit conversion to int* for the initialisation of p?
The compilation succeeds if I s/constexpr/const/ and compile with -ansi rather than -std=c++11.
iis a lvalue. However, since the expression somewhat involves lvalue-to-rvalue conversions and after that, the standard makes a constant expression, we can reasonably argue it is a NPC however perverse that might be. Note that it causes chaos in overload resolution, esp. when you're using unknown values eg. in templates. BTW I wouldn't take gcc as an benchmark here, their handling of constants is horrible.nullptrwould be required everywhere and you would never be able to assign an integral type (constant or otherwise) to a pointer without a cast. I think it makes sense to limit it only to a literal0for backwards compatibility, there is no use for using a more complicated constant expression that happens to evaluate to zero as a null pointer constant.