Is this a bug? Constexpr constructor silently becomes non-constexpr

  • A+
Category:Languages

Look at this code:

struct NonConstexpr {     NonConstexpr() { } };  template <typename T> struct Bar {     NonConstexpr nonConstexpr;      constexpr Bar() { } };  struct Foo {     Bar<void> bar;      constexpr Foo() { } }; 

Foo has a member, Foo::bar::nonConstexpr, which has a non-constexpr constructor. So, my expectation is that this should not compile. But it compiles with gcc, clang and msvc. Is this a compiler bug, or some rule allows this code to compile?

If I add a NonConstexpr member into Foo directly, the code doesn't compile anymore.

(I got this problem, because I've expected static initialization for a global Foo object, but it got dynamically initialized, and it caused a problem, because of "static initialization order fiasco")

 


Is this a compiler bug, or some rule allows this code to compile?

The rule that allows this to compile is:

10.1.5 The constexpr specifier [dcl.constexpr]
...
6. If the instantiated template specialization of a constexpr function template or member function of a class template would fail to satisfy the requirements for a constexpr function or constexpr constructor, that specialization is still a constexpr function or constexpr constructor, even though a call to such a function cannot appear in a constant expression. If no specialization of the template would satisfy the requirements for a constexpr function or constexpr constructor when considered as a non-template function or constructor, the template is ill-formed, no diagnostic required.

The above quote is taken from CPP standard draft N4713.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: