Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List-initialization of an array without temporaries - not working in GCC

Consider the following contrived example

struct A {
    A(int) {}
    A(const A&) = delete;
    ~A() {}
};

struct B {
    A a[2] = {{1}, {2}};
};

int main() {
    B b;
}

It compiles fine in clang (any version) but not in GCC (any version, any standard >= C++11)

<source>: In constructor 'constexpr B::B()':
<source>:7:8: error: use of deleted function 'A::A(const A&)'
 struct B {
        ^
<source>:3:5: note: declared here
     A(const A&) = delete;
     ^
<source>: In function 'int main()':
<source>:12:7: note: synthesized method 'constexpr B::B()' first required here
     B b;
       ^

LIVE DEMO

When A's destructor is commented out, it compiles fine also in GCC.

Question is - who is right, clang or GCC, and why?

Initially I thought GCC is wrong, but then I saw [dcl.init.list]/5 which states that temporaries are created. Though I'm not sure if that applies here or if there's another rule that overrides this.

like image 840
rustyx Avatar asked Apr 29 '19 13:04

rustyx


1 Answers

Since an array is an aggregate and aggregate initialization comes down to copy-initialization of aggregate members from the corresponding initializer-clauses, the question basically is: does copy-list-initialization (of array elements a[0] and a[1] from {1} and {2}, respectively) require copy constructor, but such question has already been answered — it does not.

BTW, GCC accepts A a = {1};, i.e. it has no problem with "direct" copy-list-initialization, but does not treat it correctly when members of aggregates are initialized.

like image 121
Language Lawyer Avatar answered Sep 20 '22 13:09

Language Lawyer