This code compiles without warning in GCC 11 and Clang 13 (in C 20 mode)
struct A {
int x, y;
};
struct B : A { };
int main () {
A a{1,2};
B b{3,4}; // Clang 12 wants B b{{3,4}}
return a.x * b.x a.y * b.y;
}
but in Clang 12 We get
<source>:10:9: warning: suggest braces around initialization of subobject [-Wmissing-braces]
B b{3,4};
https://godbolt.org/z/Kdnon9575
Might be related to:
Why does Clang 12 refuse to initialize aggregates in the C 20 way?
and these papers
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0960r3.html
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1975r0.html
Are single braces officially supported (without warnings) under C 20 for initialising these simple POD Derived classes? If so, where does the standard say that, so we can rely on it?
In C 17 the double braces are required, to avoid warnings, yes?
And in C 14 single braces are a hard error because a derived struct is not an aggregate, yes?
CodePudding user response:
C 17 as well as C 20, https://timsong-cpp.github.io/cppwp/n4659/dcl.init.aggr#12 and https://timsong-cpp.github.io/cppwp/n4868/dcl.init.aggr#15, respectively, allows brace elision for the initialization of aggregates:
Braces can be elided in an initializer-list as follows. If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the members of a subaggregate; it is erroneous for there to be more initializer-clauses than members. If, however, the initializer-list for a subaggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the members of the subaggregate; any remaining initializer-clauses are left to initialize the next member of the aggregate of which the current subaggregate is a member.
Class B in the OP's example is an aggregate in both C 17 and C 20 (as per C 17's P0017R1 and its updates primarily to [dcl.init.aggr]/1), where the requirements for what qualifies as an aggregate has been made more lenient with regard to the base class requirement.
An aggregate is an array or a class ([class]) with
- [...]
- (C 14) no base classes
- (C 17 and C 20) no virtual, private, or protected base classes
Now, the Clang diagnostic was only a warning to begin with, and as of Clang 13 it seems to have (imo correctly) have been removed for braced-elided initalization of aggregates that have base classes. It's possible the warning was a remnant corner case from C 14 where B was not an aggregate, but where the program would be ill-formed due to an invalid form of initialization.
