In some cases, braces can be elided. This is one of those cases. The outer-most braces for initializing a
and b
are optional. It is syntactically correct either way - but it's clearer to just include them. Clang is just warning you (warning, not error) about this - it's a perfectly valid warning. And as chris, points out, with -Wmissing-braces
, gcc issues the same warning. Ultimately, both compilers accept the code, which is correct; it is, after all, a valid program. That's all that matters.
From [dcl.init.aggr]:
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. [ Example:
float y[4][3] = {
{ 1, 3, 5 },
{ 2, 4, 6 },
{ 3, 5, 7 },
};
is a completely-braced initialization: 1
, 3
, and 5
initialize the first row of the array y[0]
, namely y[0][0]
,
y[0][1]
, and y[0][2]
. Likewise the next two lines initialize y[1]
and y[2]
. The initializer ends early and
therefore y[3]
s elements are initialized as if explicitly initialized with an expression of the form float()
,
that is, are initialized with 0.0
. In the following example, braces in the initializer-list are elided; however
the initializer-list has the same effect as the completely-braced initializer-list of the above example,
float y[4][3] = {
1, 3, 5, 2, 4, 6, 3, 5, 7
};
The initializer for y
begins with a left brace, but the one for y[0]
does not, therefore three elements from
the list are used. Likewise the next three are taken successively for y[1]
and y[2]
. —end example ]