Bug 25137

Summary: Warning "missing braces around initializer" causing problems with tr1::array
Product: gcc Reporter: Chris Jefferson <chris>
Component: c++Assignee: Paolo Carlini <paolo.carlini>
Status: RESOLVED FIXED    
Severity: normal CC: baffo32, bitti, dodji, fang, gcc-bugs, gdr, jason, jwakely.gcc, lidaobing, manu
Priority: P3    
Version: 4.1.0   
Target Milestone: 4.8.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2007-09-21 16:50:22

Description Chris Jefferson 2005-11-28 14:30:00 UTC
The following code:

struct S
{ int x[3]; };

void f()
{ S s = {1,2,3};}

With -Wmissing-braces (which is implied by -Wall, among others) gives:

warning: missing braces around initializer for 'int [3]'

In the specific case where a struct contains only a single array, adding the extra braces doesn't really seem that useful.

The reason it would be nice to fix this that in the definition of tr1::array in the TR1 specification (page 88, 6.2.2) says

2.An array is an aggregate ([dcl.init.aggr]) that can be initialized with the syntax 
array a = { initializer-list }; 
where initializer-list is a comma separated list of up to N elements whose types are convertible to T.
Comment 1 Andrew Pinski 2005-11-28 14:52:27 UTC
I don't see why the warning is not useful at all, in fact I rather have the C++ standard fix their wording of TR1's array.
Comment 2 Chris Jefferson 2005-11-28 15:17:01 UTC
Thats an option too, but I thought I'd see about gcc's opinion first, as I expected a much faster reply than I would get from the C++ steering committee :)

I find the warning helpful for constructs like:

struct S { int x[3]; int y[3]; }, or struct T {int x; S s;}; and such things, I felt it was less useful for a single array inside a struct.

I'm guessing one of the major reasons that it would be nice to keep the style:

array<int,3> s = {1,2,3};

is to make it look as possible like:

int s[3] = {1,2,3};
Comment 3 Gabriel Dos Reis 2005-11-28 16:15:40 UTC
Subject: Re:  Warning "missing braces around initializer" causing problems with tr1::array

"pinskia at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes:

| I don't see why the warning is not useful at all, in fact I rather
| have the C++  standard fix their wording of TR1's array.

it is not the C++ standard; but definitely a bug in the specification.
he problem shoul dbe reported there.

-- Gaby
Comment 4 Gabriel Dos Reis 2005-11-28 16:18:07 UTC
Subject: Re:   New: Warning "missing braces around initializer" causing problems with tr1::array

"chris at bubblescope dot net" <gcc-bugzilla@gcc.gnu.org> writes:

| The following code:
| 
| struct S
| { int x[3]; };
| 
| void f()
| { S s = {1,2,3};}
| 
| With -Wmissing-braces (which is implied by -Wall, among others) gives:
| 
| warning: missing braces around initializer for 'int [3]'
| 
| In the specific case where a struct contains only a single array, adding the
| extra braces doesn't really seem that useful.
| 
| The reason it would be nice to fix this that in the definition of tr1::array in
| the TR1 specification (page 88, 6.2.2) says
| 
| 2.An array is an aggregate ([dcl.init.aggr]) that can be initialized with the
| syntax 
| array a = { initializer-list }; 


I believe there is a slight confusion between a "C-array" and a TR1
class-type called "array".  You have found a bug in the TR1; would you
mind making a report?

-- Gaby
Comment 5 Chris Jefferson 2005-11-28 16:28:52 UTC
I'll make a report. Don't worry, I'm clear on the difference between tr1::array and a C array, I just wanted to check that we agree this should produce a warning (in which case I will go through the tr1::array testcases, and add the extra pair of {})
Comment 6 Chris Jefferson 2005-11-28 16:33:57 UTC
Actually, is a report really approriate? Writing array<int,3> = {1,2,3} is perfectly valid C++, just warned about with -Wmissing-braces
Comment 7 Gabriel Dos Reis 2005-11-28 18:46:04 UTC
Subject: Re:  Warning "missing braces around initializer" causing problems with tr1::array

"chris at bubblescope dot net" <gcc-bugzilla@gcc.gnu.org> writes:

| Actually, is a report really approriate? Writing array<int,3> = {1,2,3} is
| perfectly valid C++, just warned about with -Wmissing-braces

You're absolutely right!  I forgot 8.5.1/11!

Can't we have simple, general rules, without list of special cases? :-(

-- Gaby
Comment 8 Gabriel Dos Reis 2005-12-04 05:04:37 UTC
(In reply to comment #0)
> The following code:
> 
> struct S
> { int x[3]; };
> 
> void f()
> { S s = {1,2,3};}
> 
> With -Wmissing-braces (which is implied by -Wall, among others) gives:
> 
> warning: missing braces around initializer for 'int [3]'
> 
> In the specific case where a struct contains only a single array, adding the
> extra braces doesn't really seem that useful.
> 
> The reason it would be nice to fix this that in the definition of tr1::array in
> the TR1 specification (page 88, 6.2.2) says

After more thoughts on this issue, it appears to me that it is asking for
a special casing  justforo tr1::array<> to work.  I don't know whether
that is a workable approach.  I would reommend -Wno-missing-braces in this
specific case.  Thoughts?

Comment 9 Jonathan Wakely 2005-12-06 13:07:13 UTC
I've often found this warning to be a nuisance, because it's correct and well-defined to omit some braces from the initializer.

There are many cases where the warning is useful, e.g. with aggregates that have several members (which may be aggregates themselves), but when the type contains a single member (possibly of array type) then the extra braces are often just clutter.

Pff the top of my head, I would like a way to disable the warning iff the aggregate has a single member and iff the initializer contains exactly the right number of elements to initialize that single member.  e.g.

struct S { int s[3]; };
S s1 = { 1, 1, 1 };       // OK   - missing braces but correct number
S s2 = { 1, 1 };          // WARN - no initializer for s2.s[2]
S s3 = { { 1, 1 } };      // OK   - braces correct but missing init

I don't think this would be useful only for tr1::array, but for lots of similar code.  Obvious and closely-related examples are the block and carray templates in Austern and Josuttis's books.
Comment 10 Andrew Pinski 2006-04-04 05:44:33 UTC
*** Bug 27015 has been marked as a duplicate of this bug. ***
Comment 11 Paolo Carlini 2007-09-21 16:50:21 UTC
Looking into it: I mean to investigate whether a relaxed warning per Comment #9 is implementable in a decently clean way.
Comment 12 Matti Rintala 2010-12-17 11:21:06 UTC
Has there been any progress with this bug/problem? The latest C++0x draft still explicitly allows "array a<T, N> = { initializer-list };" (23.3.1/2), but at least gcc 4.5.1 still gives a warning with -Wall enabled.
Comment 13 Jonathan Wakely 2010-12-17 11:33:48 UTC
GCC allows it too, otherwise it would be an error not a warning.

But no, there hasn't been any progress I know of, the warning is still given for std::array in C++0x mode as well as tr1::array
Comment 14 Paolo Carlini 2010-12-17 12:22:50 UTC
I'm sorry I don't mean to wrk on this over the next weeks, maybe sombody will ne interested in picking my patch in this thread and completing it (both for C and C++): http://gcc.gnu.org/ml/gcc/2009-11/msg00430.html http://gcc.gnu.org/ml/gcc/2009-11/msg00468.html
Comment 15 baffo32 2011-08-27 08:53:59 UTC
(In reply to comment #13)
> GCC allows it too, otherwise it would be an error not a warning.

I believe GCC fails for multi-dimensional arrays?

array<array<int,2>,2> a{ {1,2},{3,4} }; // won't compile without another pair of {}
Comment 16 Paolo Carlini 2011-08-30 09:41:23 UTC
Maybe Dodji is interested in working on this?!? Can be quite annoying with tr1::array and std::array in C++11, of course.
Comment 17 Jason Merrill 2012-05-26 21:21:51 UTC
Hmm.  I see the argument, but it seems to me that the purpose of -Wmissing-braces is precisely to warn about this sort of thing.  Perhaps it just shouldn't be part of -Wall in C++ mode, particularly in C++11 since initializer lists are a lot more flexible now.
Comment 18 Paolo Carlini 2012-05-26 21:46:03 UTC
Let's take it out of C++ then.
Comment 19 paolo@gcc.gnu.org 2012-05-28 17:42:34 UTC
Author: paolo
Date: Mon May 28 17:42:29 2012
New Revision: 187937

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=187937
Log:
/c-family
2012-05-28  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/25137
	* c-opts.c (c_common_handle_option): For C++ -Wall doesn't enable
	-Wmissing_braces.

2012-05-28  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/25137
	* doc/invoke.texi: Document -Wmissing-braces not enabled by -Wall
	for C++.

/testsuite
2012-05-28  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/25137
	* g++.dg/warn/Wbraces3.C: New.
	* g++.dg/warn/Wbraces4.C: Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/warn/Wbraces3.C
    trunk/gcc/testsuite/g++.dg/warn/Wbraces4.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/c-family/ChangeLog
    trunk/gcc/c-family/c-opts.c
    trunk/gcc/doc/invoke.texi
    trunk/gcc/testsuite/ChangeLog
Comment 20 Paolo Carlini 2012-05-28 17:44:52 UTC
Done.
Comment 21 Manuel López-Ibáñez 2012-05-29 08:03:07 UTC
Hi Paolo (cc. Jason),

for options that enable other options only in specific languages, it would be good to use the new LangEnabledBy in the .opt files. (For example, this will make -Wno-missing-braces -Wall work as expected).
Comment 22 Paolo Carlini 2012-05-29 09:05:51 UTC
Oops, sorry, I think at some point I wondered if something was in order but then forgot. If you can tell me the right syntax, I can add it, must be quite simple, right?
Comment 23 Manuel López-Ibáñez 2012-05-29 09:22:05 UTC
It is explained here http://gcc.gnu.org/onlinedocs/gccint/Option-properties.html#Option-properties

A patch like the following should work (plus removing the special handling in c-opts.c)

Index: c.opt
===================================================================
--- c.opt	(revision 187628)
+++ c.opt	(working copy)
@@ -463,7 +463,7 @@
 Warn about suspicious declarations of \"main\"
 
 Wmissing-braces
-C ObjC C++ ObjC++ Var(warn_missing_braces) Warning
+C ObjC C++ ObjC++ Var(warn_missing_braces) Warning LangEnabledBy(C ObjC, Wall)
 Warn about possibly missing braces around initializers
 

There is also EnabledBy, which is unconditional. The plan is to convert sub-options to use this infrastructure. There is also some functionality missing:

* An option enabled only if two options are combined. (-Wextra && -Wunused enable -Wunused-parameter).

* An option enabled by some arbitrary condition.

And some options are problematic because they currently have bugs: warn_format is 0 by default but the value of -Wformat in the gcc_opts structure is -1, thus calling warning(OPT_Wformat) without checking warn_format means enabled by default. Some tests expect such diagnostics to be enabled by default. :-(
Comment 24 Paolo Carlini 2012-05-29 09:41:01 UTC
Thanks. I'm going to test the patchlet momentarily, I think it qualifies as obvious.