https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106666
Bug ID: 106666 Summary: Anonymous struct incorrectly allows types with constructors if placed in a known sized array Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: twmouton at gmail dot com Target Milestone: --- Consider the following: #include <iostream> #include <memory> struct ConstructMe { ConstructMe() { std::cout << "I have been constructed" << std::endl; } ~ConstructMe() { std::cout << "I have been destructed" << std::endl; } }; struct Foo { Foo() : me{ std::make_unique< ConstructMe >() } { std::cout << "Foo" << std::endl; } struct { std::unique_ptr< ConstructMe > me[1]; }; }; int main() { Foo f; return 0; } Compiled with g++ 12.1 using only -std=c++17. If you remove the "[1]" after "me" the compiler will emit the error "error: member 'std::unique_ptr<ConstructMe> Foo::<unnamed struct>::me' with constructor not allowed in anonymous aggregate" with similar errors for the existence of a destructor and copy-assignment operator. To make matters worse, if you do make this an array then the object is only constructed if it's included in the member initialization list (in above - remove the unique_ptr and use just a plain ConstructMe to see that it is not constructed) and it is never destructed. In the example above using unique_ptr, this means the memory is leaked when Foo falls out of scope. Since this is an extension, I am not sure what the correct behavior should be but it should be consistent regardless of an object is in an array or single member. I see two options for this. 1. Make it so the objects in an array that have constructor/destructor/copy-assignment defined emit the same errors as not having an array. 2. Objects with zero argument constructors should be allowed in an anonymous struct, and should be constructed/destructed as if they were direct members of the enclosing struct. For what it's worth, clang seems to have chosen option 2.