missing braces around initializer

B

Boon

Hello,

One of the examples in the C89 draft is

float y[4][3] = {
{ 1, 3, 5 },
{ 2, 4, 6 },
{ 3, 5, 7 },
};

is a definition with a fully bracketed initialization: 1, 3, and 5
initialize the first row of the array object 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, so y[3] is initialized with
zeros. Precisely the same effect could have been achieved by

float y[4][3] = {
1, 3, 5, 2, 4, 6, 3, 5, 7
};

The initializer for y[0] does not begin with a left brace, so three
items from the list are used. Likewise the next three are taken
successively for y[1] and y[2] .

gcc seems to dislike the second form.

foo.c:2: warning: missing braces around initializer
foo.c:2: warning: (near initialization for 'y[0]')

AFAIU, a compiler is free to warn about anything, but this warning seems
somewhat wrong.

Would you consider a "bug" in gcc? (QoI perhaps.)

Regards.
 
K

Keith Thompson

Boon said:
One of the examples in the C89 draft is

float y[4][3] = {
{ 1, 3, 5 },
{ 2, 4, 6 },
{ 3, 5, 7 },
};

is a definition with a fully bracketed initialization: 1, 3, and 5
initialize the first row of the array object 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, so y[3] is initialized with
zeros. Precisely the same effect could have been achieved by

float y[4][3] = {
1, 3, 5, 2, 4, 6, 3, 5, 7
};

The initializer for y[0] does not begin with a left brace, so three
items from the list are used. Likewise the next three are taken
successively for y[1] and y[2] .

gcc seems to dislike the second form.

foo.c:2: warning: missing braces around initializer
foo.c:2: warning: (near initialization for 'y[0]')

AFAIU, a compiler is free to warn about anything, but this warning
seems somewhat wrong.

Would you consider a "bug" in gcc? (QoI perhaps.)

I agree with gcc's assessment. Omitting the inner braces is
error-prone. Suppose you accidentally leave out the 6. This:

float y[4][3] = {
{ 1, 3, 5 },
{ 2, 4 },
{ 3, 5, 7 },
};

is more obviously wrong, and more obvious about where the error is,
than this:

float y[4][3] = {
1, 3, 5, 2, 4, 3, 5, 7
}

The language allows you to omit the inner braces, but why would you
want to?
 
K

Keith Thompson

Twirlip of the Mists said:
The language allows you to omit the inner braces, but why would you want
to?

There is one fairly common case, auto structs and arrays that you want
initialized to 0, 0.0 or NULL as appropriate. Consider this example:

struct fred {
int x;
float y[3];
char *message[2];
} barney[3][4][7] = {0};

"{0}" is a universal initializer that works for anything (I believe). I
would like compilers to treat it as a special exception if they are going
to warn about missing braces or struct members in initializers. I found
gcc could be worse: "{{{{0}}}}" will silence the warning. At least you
don't need to initialize all the members.

Agreed -- and yes, it's annoying that gcc warns about this.

But for anything other than {0}, I prefer to use fully braced
initializers.

(And yes, hexapodia *is* the key insight.)
 
R

Robert Gamble

Boon said:
One of the examples in the C89 draft is
         float y[4][3] = {
                  { 1, 3, 5 },
                  { 2, 4, 6 },
                  { 3, 5, 7 },
         };
is a definition with a fully bracketed initialization: 1, 3, and 5
initialize the first row of the array object 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, so y[3] is initialized with
zeros.  Precisely the same effect could have been achieved by
         float y[4][3] = {
                  1, 3, 5, 2, 4, 6, 3, 5, 7
         };
The initializer for y[0] does not begin with a left brace, so three
items from the list are used.  Likewise the next three are taken
successively for y[1] and y[2] .
gcc seems to dislike the second form.
foo.c:2: warning: missing braces around initializer
foo.c:2: warning: (near initialization for 'y[0]')
AFAIU, a compiler is free to warn about anything, but this warning seems
somewhat wrong.

     Seems fine to me.  What do you think is "wrong" with it?
Would you consider a "bug" in gcc? (QoI perhaps.)

     It seems to me that gcc is trying to encourage you to be
explicit about exactly which initializers belong to exactly which
initialized elements.  Some people regard such encouragement as
helpful, increasing Q.  Others (you, I guess) regard it as the
behavior of a nagging nanny, decreasing Q.  Maybe there's a
compile-time flag that will turn this warning off if it
displeases you.

You actually have to tell gcc to warn about this with -Wmissing-braces
(or use -Wall which includes it). If you want to use -Wall and
exclude this warning you can add -Wno-missing-braces.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,805
Latest member
ClydeHeld1

Latest Threads

Top