What is the cause of his C++20 brace initialization backwards compatibility failure?

Viewed 100

I found an interesting case where valid(?) C++17 code fails when compiling with C++20. The simplest reproduction is a struct with an explicit default constructor. On C++17, this code works fine. In C++20, it fails to compile. Tested on Clang and GCC.

struct A {
    int val;
    A() = default;

    // When commented out: only works with C++17 or earlier
    // When uncommented: works up to C++20
    //A(int val) : val(val) { }
};

int main() {
    A a{4};
}

Does anyone know why this is occurring?

1 Answers

In C++17, A is an aggregate. In C++20, the rules were changed so that any user-declared constructor prevents the class from being an aggregate, even if you default it on its first declaration. Therefore, in C++17, aggregate initialization can be used, while in C++20, the code is invalid because there is no constructor that is suitable for the initialization A a{4};.

Related