Home > Net >  why "missing double brace warning" for BaseClass Aggregate initialisation in Clang 12 but
why "missing double brace warning" for BaseClass Aggregate initialisation in Clang 12 but

Time:01-12

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.

  •  Tags:  
  • Related