Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are many curly brackets treated differently by C++ compilers?

In the following C++20 program I put by mistake one extra pair of curved braces {} in B{{{{A{}}}}}:

#include <iostream>

struct A
{
    A() { std::cout << "A() "; }
    A( A&& ) = delete;
    ~A() { std::cout << "~A() "; }
};

struct B { std::initializer_list<A> l; };

int main()
{
    [[maybe_unused]] auto x = B{{{{A{}}}}};
    std::cout << ". ";
}

Clang rejected it, however with a strange error:

error: call to deleted constructor of 'const A'

But to my surprise GCC accepted it( https://gcc.godbolt.org/z/aPWe13xfc ).

Could you please explain why GCC accepts it (how does it treat extra curved braces)?

like image 927
Fedor Avatar asked Jul 18 '21 09:07

Fedor


1 Answers

B{…}, since the single element of the initializer list is not designated and is not of type B (as it has no type at all), is aggregate initialization ([dcl.init.list]/3.4). B::l is thus copy-initialized from {{{A{}}}}; it's a specialization of std::initializer_list, so /3.6 and /5 apply. An "array of 1 const A" is created, and {{A{}}} is the initializer for its single element.

We can thus reduce the code to

const A a = {{A{}}};

with no mention of B at all, and indeed Clang and GCC produce the same disagreement for this line. Clang appears to be correct to reject it: that initialization is sent to constructors by /3.7, and obviously there is no constructor that could be viable (thus the error about the deleted move constructor).

Oddly, removing the extra pair of braces here (or in the original) causes both compilers to accept:

const A a = {A{}};

despite the fact that A is not an aggregate and so /3.7 still applies. Presumably both compilers are overenthusastically performing "guaranteed copy elision" (albeit to different degrees), identifying the prvalue A{} with an object eventually to be initialized by it; that, however, takes place only per [dcl.init.general]/16.6.1, which never comes into play in this analysis.

like image 172
Davis Herring Avatar answered Oct 28 '22 20:10

Davis Herring