https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92385
--- Comment #6 from Carl <edquist at cs dot wisc.edu> --- > I'm not sure if () and {} are semantically equivalent [in this case]. For what it's worth, (not sure if I'm allowed to paste a link here, but) on cppreference.com [1] under "Constructors and member initializer lists", it describes the following forms for "member-initializers" in "the body of a function definition of any constructor" : class-or-identifier ( expression-list(optional) ) (1) class-or-identifier brace-init-list (2) (since C++11) And about these it says: 1) Initializes the base or member named by class-or-identifier using direct initialization or, if expression-list is empty, value-initialization 2) Initializes the base or member named by class-or-identifier using list-initialization (which becomes value-initialization if the list is empty and aggregate-initialization when initializing an aggregate) So it seems in this case of "a()" (1) vs "a{}" (2), either one results in "value-initialization", which is further described here [2]. The following forms are described for value-initialization: T() (1) T{} (5) (since C++11) About which it says: 1,5) when a nameless temporary object is created with the initializer consisting of an empty pair of parentheses [or braces (since C++11)]; But then it goes on to say: In all cases, if the empty pair of braces {} is used and T is an aggregate type, aggregate-initialization is performed instead of value-initialization. (And notably, an array is an aggregate type.) Then the page on aggregate-initialization[3] goes on to describe the many semantic effects of aggregate initialization... The part that seems to apply is If the number of initializer clauses is less than the number of members or initializer list is completely empty, the remaining members are initialized by empty lists, in accordance with the usual list-initialization rules (which performs value-initialization for non-class types and non-aggregate classes with default constructors, and aggregate initialization for aggregates). (since C++11) I presume our "struct item" counts as a "non-aggregate class with default constructor", which would result in value-initialization, but my lawyer glasses are a little fuzzy here. Whereas, the way I read the value-initialization rules, if "()" is used (that is, not "the empty pair of braces {}"), then this rule applies: 3) if T is an array type, each element of the array is value-initialized; Which means that for every element of the array this applies: 1) if T is a class type with [...] a user-provided [...] constructor, the object is default-initialized; So, a bit round-about, but it seems like both routes would result in value-initialization, which ends up meaning each element gets default-initialized. But you have to squint real hard, and the rules about how to get there seem to follow surprisingly different-looking paths... Maybe that (partially) explains the different code-paths in g++. Carl [1] https://en.cppreference.com/w/cpp/language/initializer_list [2] https://en.cppreference.com/w/cpp/language/value_initialization [3] https://en.cppreference.com/w/cpp/language/aggregate_initialization