简体   繁体   中英

Compiler generated default constructor with constexpr confusing behavior

Sample 1

template <typename T>
struct A
{

    constexpr A() = default;
    T x;
};

int main(){
    static_assert(A<int>{}.x == int{}, "FAILED");
}

Sample 2

struct A
{
    constexpr A() = default;
    int x;
};

int main(){
    static_assert(A{}.x == int{}, "Not Equal");
}

I am confused as to how the first sample compiles and passes the static assert, while the second one fails to compile as mentioned in the constexpr defaulted default constructors with Error: defaulted definition of default constructor is not constexpr .

Tried reading the following but couldn't understand as to how first one works and other doesn't. http://eel.is/c++draft/class.ctor#class.default.ctor-4

A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]) to create an object of its class type ([intro.object]), when it is needed for constant evaluation ([expr.const]), or when it is explicitly defaulted after its first declaration. The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer and an empty compound-statement. If that user-written default constructor would be ill-formed, the program is ill-formed. If that user-written default constructor would satisfy the requirements of a constexpr constructor ([dcl.constexpr]), the implicitly-defined default constructor is constexpr. Before the defaulted default constructor for a class is implicitly defined, all the non-user-provided default constructors for its base classes and its non-static data members are implicitly defined. [ Note: An implicitly-declared default constructor has an exception specification ([except.spec]). An explicitly-defaulted definition might have an implicit exception specification, see [dcl.fct.def]. — end note ]

Thank You!

The following can shed some light on the issue:

int main(){
    constexpr A<int> a;
}

Attempting to call the constexpr constructor produces this error (gcc):

<source>: In function 'int main()':
<source>:12:22: error: uninitialized 'const a' [-fpermissive]
   12 |     constexpr A<int> a;
      |                      ^
<source>:4:8: note: 'const struct A<int>' has no user-provided default constructor
    4 | struct A
      |        ^
<source>:7:15: note: constructor is not user-provided because it is explicitly defaulted in the class body
    7 |     constexpr A() = default;
      |               ^
<source>:8:7: note: and the implicitly-defined constructor does not initialize 'int A<int>::x'
    8 |     T x;
      |       ^

However, if I am not missing something, the constexpr constructor should already be an error, because it cannot be constexpr (see here ).

Both gcc and clang accept your code, but both produce an error for attempting to call the constexpr constructor. I suppose it is a compiler bug.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM