In the following example: #include <iostream> using std::cerr; struct S { int n; }; struct X { X(int) {} }; void f(void*) { cerr << "Pointer!\n"; } void f(X) { cerr << "X!\n"; } int main() { f(S().n); } With GCC 4.7.0-20120128 with the --std=c++11 flag, the output is "X!". The correct output would be "Pointer!". The reason is that S's implicit default constructor is constexpr, so it value-initializes n. Therefore S().n is a zero-valued integer constant expression, whose conversion to a pointer is preferred over the user-defined conversion to X. (This example was taken from Chandler Carruth's talk at the GoingNative 2012 conference.)
(In reply to comment #0) The core language is in the process to make it clear, that S().n no longer is a null-pointer constant, see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#903 This would mean that the current behaviour is as intended. I would make the outcome of this issue dependent on the final CWG 903 decision.
suspending
A simpler test case is: $ cat test.cc const long kNullPtr = 0; const long* ptr = kNullPtr; $ g++-4.7pre -c test.cc -std=gnu++11 test.cc:2:19: error: invalid conversion from ‘long int’ to ‘const long int*’ [-fpermissive] $ g++-4.7pre --version g++-4.7pre (GCC) 4.7.1 20120412 (prerelease) I'm going to unsuspend this because DR903 is "ready", and gcc-4.7's behavior doesn't match either the proposed wording or the current definition of C++11. The proposed wording discusses a change to C++17 rather than to C++11 (we can tell because it adds a "C.3 C++ and ISO C++ 2011" section), so the new error should only show up under -std=gnu++17, and be a warning in -std=gnu++11.
17?
"17" was the rough consensus at Kona for the target for the next standard. You could use -std=c++1y or c++1x or whatever instead.
Oh, Ok, I wasn't there. In GCC we currently use -std=c++1y, but you know that.
Oops, I didn't actually realize you'd allocated an option for that in 4.8, and was just making one up. Sorry for the distraction.
DR 903 is a DR against C++11 ([diff.cpp03.conv] identifies it as an incompatibility with C++03, not with C++11). Clang also implements DR 903 in C++11 mode.
*** Bug 88655 has been marked as a duplicate of this bug. ***
*** Bug 77712 has been marked as a duplicate of this bug. ***
Here is a testcase which tests all of the null pointerness in C++11 (+): #include <cstddef> extern "C" int puts(const char*); typedef unsigned long uint64_t; typedef long int64_t; struct Foo { Foo(int64_t) { } }; bool t = true; void foo(const char*) { if (t) __builtin_abort(); puts("In foo(const char*)"); } void foo(const Foo&) { if (!t) __builtin_abort(); puts("In foo(const Foo&)"); } int main() { #if __cplusplus >= 201103L t= true; #else t= false; #endif foo((int)0); foo((unsigned)0); foo((short)0); foo((unsigned short)0); foo((int64_t)0); foo((uint64_t)0); foo(int()); #if __cplusplus >= 201103L foo(int{}); t= false; foo(nullptr); #endif foo(0u); foo(0ul); foo(0ull); foo(0); foo(NULL); } ---- CUT ---- We get this right for C++98 but wrong for C++11.
*** Bug 96761 has been marked as a duplicate of this bug. ***
*** Bug 107260 has been marked as a duplicate of this bug. ***
*** Bug 116619 has been marked as a duplicate of this bug. ***