Go Back   Rhinocerus > Newsgroup > Newsgroup comp.lang.c



Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 02-08-2010, 06:13 PM
Tor Rustad
Guest
 
Posts: n/a
Default Missing braces around {0} initializer?!

I am puzzled by a warning, I get when using {0} as initializer. This
snippet demonstrate the warning:


struct tlv_item {
int tag;
int len;
char *val;
};

int main(void)
{
struct tlv_item tlv_1[10] = { 0 }; /* Why warning?! */
struct tlv_item tlv_2[10] = { {0,0,0} }; /* OK */

tlv_1[0].tag = tlv_2[0].tag = 1;

return 0;
}

$ gcc -Wall -ansi -pedantic clc_demo.c
clc_demo.c: In function ‘main’:
clc_demo.c:9: warning: missing braces around initializer
clc_demo.c:9: warning: (near initialization for ‘tlv_1[0]’)

$ gcc --version
gcc (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)


There was no warning with { {0,0,0} }, but I thought { 0 } was perfectly
conforming C as initializer above. Is this warning a compiler specific
thing which I can turn off somehow, or am I completely missing something
in Standard C here???

--
Tor <echo bwzcab@wvtqvm.vw | tr i-za-h a-z>
Reply With Quote
Alt Today
Advertising
Google Adsense
 
and become member of Rhinocerus
Standard Sponsored Links

  #2 (permalink)  
Old 02-08-2010, 06:19 PM
Ben Pfaff
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

Tor Rustad <bwzcab@wvtqvm.vw> writes:
[...]
> There was no warning with { {0,0,0} }, but I thought { 0 } was
> perfectly conforming C as initializer above. Is this warning a
> compiler specific thing which I can turn off somehow, or am I
> completely missing something in Standard C here???


{ 0 } is perfectly conforming C, even in this case. GCC is
nevertheless warning about it because it thinks you probably made
a mistake. You can turn off the warning (GCC has an option for
that, I'm sure), or you can write out the initializer in full,
which will placate GCC, or you can ignore the warning.
--
"I should killfile you where you stand, worthless human." --Kaz
Reply With Quote
  #3 (permalink)  
Old 02-08-2010, 06:43 PM
Seebs
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

On 2010-02-08, Tor Rustad <bwzcab@wvtqvm.vw> wrote:
> I am puzzled by a warning, I get when using {0} as initializer. This
> snippet demonstrate the warning:


> There was no warning with { {0,0,0} }, but I thought { 0 } was perfectly
> conforming C as initializer above. Is this warning a compiler specific
> thing which I can turn off somehow, or am I completely missing something
> in Standard C here???


I believe the answer is neither.

Rather, it's a *warning*. A helpful warning that, if you are initializing
an array of structures, it is clearer to put braces around the structure
initializers. Which it is. Most people won't be quite sure of the semantics
of something like

struct { int a, b, c; } foo[] = { 1, 2, 3, 4 };

and thus gcc warns you that you should probably have the right number of
levels of braces.

It's not saying your code violates the standard, just that your code has
characteristics which are very strongly suggestive that you have made a
typo.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
Reply With Quote
  #4 (permalink)  
Old 02-08-2010, 08:13 PM
Keith Thompson
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

Seebs <usenet-nospam@seebs.net> writes:
> On 2010-02-08, Tor Rustad <bwzcab@wvtqvm.vw> wrote:
>> I am puzzled by a warning, I get when using {0} as initializer. This
>> snippet demonstrate the warning:

>
>> There was no warning with { {0,0,0} }, but I thought { 0 } was perfectly
>> conforming C as initializer above. Is this warning a compiler specific
>> thing which I can turn off somehow, or am I completely missing something
>> in Standard C here???

>
> I believe the answer is neither.
>
> Rather, it's a *warning*. A helpful warning that, if you are initializing
> an array of structures, it is clearer to put braces around the structure
> initializers. Which it is. Most people won't be quite sure of the semantics
> of something like
>
> struct { int a, b, c; } foo[] = { 1, 2, 3, 4 };
>
> and thus gcc warns you that you should probably have the right number of
> levels of braces.
>
> It's not saying your code violates the standard, just that your code has
> characteristics which are very strongly suggestive that you have made a
> typo.


Which are very strongly suggestive *to gcc*.

The initializer { 0 } sets all members of the initialized object to
zero. This is, or should be, a common C idiom. gcc just doesn't
recognize it.

gcc probably has an option to turn off the warning, but that option
will probably turn off some useful warnings as well. For example,
I definitly *want* a warning for
struct { int a, b, c; } foo[] = { 1, 2, 3, 4 };
but I don't want one for:
struct { int a, b, c; } foo[] = { 0 };
I don't think gcc distinguishes between those two cases.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Reply With Quote
  #5 (permalink)  
Old 02-08-2010, 08:44 PM
Andrew Poelstra
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

On 2010-02-08, Keith Thompson <kst-u@mib.org> wrote:
>
> The initializer { 0 } sets all members of the initialized object to
> zero. This is, or should be, a common C idiom. gcc just doesn't
> recognize it.
>
> gcc probably has an option to turn off the warning, but that option
> will probably turn off some useful warnings as well. For example,
> I definitly *want* a warning for
> struct { int a, b, c; } foo[] = { 1, 2, 3, 4 };
> but I don't want one for:
> struct { int a, b, c; } foo[] = { 0 };
> I don't think gcc distinguishes between those two cases.
>


Even for

struct test {
int a;
int b;
int c;
}

int main(void) {
struct test t = { 0 };
return 0;
}

gcc warns me. And it's a particularly irritating warning because
it individually lists each struct member with a message that I am
"missing initialization".

So for some structs I get six or seven warning messages for every
single variable I initialize that way, so I then have to type out
struct test t = { 0, 0, 0 } like a goof or just not initialize it
at all (which gcc is perfectly fine with).

Reply With Quote
  #6 (permalink)  
Old 02-08-2010, 08:46 PM
Tor Rustad
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

Seebs wrote:
> On 2010-02-08, Tor Rustad <bwzcab@wvtqvm.vw> wrote:
>> I am puzzled by a warning, I get when using {0} as initializer. This
>> snippet demonstrate the warning:

>
>> There was no warning with { {0,0,0} }, but I thought { 0 } was perfectly
>> conforming C as initializer above. Is this warning a compiler specific
>> thing which I can turn off somehow, or am I completely missing something
>> in Standard C here???

>
> I believe the answer is neither.
>
> Rather, it's a *warning*. A helpful warning that, if you are initializing
> an array of structures, it is clearer to put braces around the structure
> initializers. Which it is. Most people won't be quite sure of the semantics
> of something like
>
> struct { int a, b, c; } foo[] = { 1, 2, 3, 4 };
>
> and thus gcc warns you that you should probably have the right number of
> levels of braces.
>
> It's not saying your code violates the standard, just that your code has
> characteristics which are very strongly suggestive that you have made a
> typo.


I don't agree this was a useful warning, {0} had a crystal clear meaning
for me, until I saw that warning. If giving a warning for missing
braces, then {0} should have been an exception. Using { {0,0,0} }
instead, just add noise and using memset() even require an extra line.

After investigating the gcc man page, I finally (after zillion scrolls):

-Wmissing-braces
Warn if an aggregate or union initializer is not fully
bracketed. In the following example, the initializer for a is not fully
bracketed, but that for b is fully
bracketed.

int a[2][2] = { 0, 1, 2, 3 };
int b[2][2] = { { 0, 1 }, { 2, 3 } };

This warning is enabled by -Wall.



sooo... it appears we need to turn off -Wall, and that's not something I
will do.

Arrgh!

--
Tor <echo bwzcab@wvtqvm.vw | tr i-za-h a-z>
Reply With Quote
  #7 (permalink)  
Old 02-08-2010, 08:48 PM
Andrew Poelstra
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

On 2010-02-08, Andrew Poelstra <apoelstra@localhost.localdomain> wrote:
> On 2010-02-08, Keith Thompson <kst-u@mib.org> wrote:
>>
>> The initializer { 0 } sets all members of the initialized object to
>> zero. This is, or should be, a common C idiom. gcc just doesn't
>> recognize it.
>>
>> gcc probably has an option to turn off the warning, but that option
>> will probably turn off some useful warnings as well. For example,
>> I definitly *want* a warning for
>> struct { int a, b, c; } foo[] = { 1, 2, 3, 4 };
>> but I don't want one for:
>> struct { int a, b, c; } foo[] = { 0 };
>> I don't think gcc distinguishes between those two cases.
>>

>
> Even for
>
> struct test {
> int a;
> int b;
> int c;
> }


Missing a semicolon here.

>
> int main(void) {
> struct test t = { 0 };
> return 0;
> }
>
> gcc warns me. And it's a particularly irritating warning because
> it individually lists each struct member with a message that I am
> "missing initialization".
>


For that specific test program, it only gave me two lines of warnings
(plus an "unused variable" message). The first was "missing initializer"
and the second was "near initialization of something".

So perhaps I am thinking of g++ warning of every member.

> So for some structs I get six or seven warning messages for every
> single variable I initialize that way, so I then have to type out
> struct test t = { 0, 0, 0 } like a goof or just not initialize it
> at all (which gcc is perfectly fine with).
>


Reply With Quote
  #8 (permalink)  
Old 02-08-2010, 08:50 PM
Seebs
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

On 2010-02-08, Keith Thompson <kst-u@mib.org> wrote:
> The initializer { 0 } sets all members of the initialized object to
> zero. This is, or should be, a common C idiom. gcc just doesn't
> recognize it.


Hmm. I wouldn't have done that; I'd have done { { 0 } } to show that I was
aware that I was initializing an aggregate of aggregates.

I do agree that it might make sense to special-case the case where there's
exactly one initializer, and it's zero.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
Reply With Quote
  #9 (permalink)  
Old 02-08-2010, 09:04 PM
Ben Pfaff
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

Andrew Poelstra <apoelstra@localhost.localdomain> writes:

> Even for
>
> struct test {
> int a;
> int b;
> int c;
> }
>
> int main(void) {
> struct test t = { 0 };
> return 0;
> }
>
> gcc warns me. And it's a particularly irritating warning because
> it individually lists each struct member with a message that I am
> "missing initialization".


It's annoying.

In practice I often end up doing this:

struct test {
int a;
int b;
int c;
};

#define TEST_INITIALIZER { 0, 0, 0 }

int main(void) {
struct test t = TEST_INITIALIZER;
return 0;
}

--
"I'm not here to convince idiots not to be stupid.
They won't listen anyway."
--Dann Corbit
Reply With Quote
  #10 (permalink)  
Old 02-08-2010, 09:14 PM
Kaz Kylheku
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

On 2010-02-08, Ben Pfaff <blp@cs.stanford.edu> wrote:
> Andrew Poelstra <apoelstra@localhost.localdomain> writes:
>
>> Even for
>>
>> struct test {
>> int a;
>> int b;
>> int c;
>> }
>>
>> int main(void) {
>> struct test t = { 0 };
>> return 0;
>> }
>>
>> gcc warns me. And it's a particularly irritating warning because
>> it individually lists each struct member with a message that I am
>> "missing initialization".

>
> It's annoying.


GCC is becoming annoying. The project has been taken over by twits.

Here is a gem: they decided that it's okay to generate deliberately broken
code when the function can detect at compile time that a function pointer
is being ``misused'' (cast to a different function type, and used to make
a call).

So I upgrade the compiler, rebuild an embedded Linux distro, boot it, and blam!
OpenSSH fails on key generation with a strange error, aborting on some kind
of illegal instruction.

After spending the time to trace the problem, I ended up patching this
goddamned idiocy out of the compiler.

Can you believe the reasoning? Let's break the code /deliberately/ just because
it invokes undefined behavior, but since we can't prove that it's reached,
let's translate the program successfully anyway. Let's give the distro
maintainer a clean build, so he can boot the system and go hunting for the
problem in the sea of shiny new executables.
Reply With Quote
  #11 (permalink)  
Old 02-08-2010, 09:16 PM
Seebs
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

On 2010-02-08, Kaz Kylheku <kkylheku@gmail.com> wrote:
> Here is a gem: they decided that it's okay to generate deliberately broken
> code when the function can detect at compile time that a function pointer
> is being ``misused'' (cast to a different function type, and used to make
> a call).


Specifically, when it's cast to a function type which does not match the
function *being called*.

And it should give you copious warnings when it triggers that, and it's
fixed as of OpenSSH 0.9.8f or so.

I seem to recall being told by someone closer to the code that the reason
is that otherwise the PPC compiler tended to blow up spectacularly trying
to optimize mismatched calls.

BTW, this sounds *eerily* familiar. When I encountered it, it involved
someone using a heavily-hacked OpenSSH 0.9.8 library, rather than the 0.9.8g
we shipped with that version of the product, because it had some specific
other bit of magic going on that was needed. I told the support people to
point the customer at the specific patches (I think that was 0.9.8f) to
openssh which fixed the calls to use the correct types.

But honestly, overall, I like that one. I am quite happy to have the compiler
throw out fierce warnings about something that is known to have a real chance
of blowing up in exciting ways, and to die cleanly rather than executing
garbage.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
Reply With Quote
  #12 (permalink)  
Old 02-08-2010, 09:24 PM
Keith Thompson
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

Seebs <usenet-nospam@seebs.net> writes:
> On 2010-02-08, Keith Thompson <kst-u@mib.org> wrote:
>> The initializer { 0 } sets all members of the initialized object to
>> zero. This is, or should be, a common C idiom. gcc just doesn't
>> recognize it.

>
> Hmm. I wouldn't have done that; I'd have done { { 0 } } to show that I was
> aware that I was initializing an aggregate of aggregates.


Ok. Would you write { { { 0 } } } for an aggregate of aggregates of
aggregates? And so forth.

> I do agree that it might make sense to special-case the case where there's
> exactly one initializer, and it's zero.


Right. The point is that { 0 } means, regardless of the depth of the
object being initialized, that all members and elements are
initialized to zero (whatever "zero" means for the particular type).
The object can even be a scalar. And there's no other way to say
that.

On the other hand, { 0 } also means initializing a single-element
array or a single-member struct (or a union).

The rule that allows us to use { 0 } as a generic zero initializer is
C99 6.7.8p21:

If there are fewer initializers in a brace-enclosed list
than there are elements or members of an aggregate, or fewer
characters in a string literal used to initialize an array of
known size than there are elements in the array, the remainder
of the aggregate shall be initialized implicitly the same as
objects that have static storage duration.

Because the syntax requires at least one initializer between the
braces, you have to initialize the first element explicitly and leave
the rest, if any, to be initialized implicitly.

I'd like to see the syntax expanded to allow empty braces:

some_type obj = { };

with the same meaning as:

some_type obj = { 0 };

With the "{ }" syntax, you're unambiguously leaving all the members to
be initialized implicitly (and there'd be nothing for gcc to complain
about).

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Reply With Quote
  #13 (permalink)  
Old 02-08-2010, 09:36 PM
Seebs
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

On 2010-02-08, Keith Thompson <kst-u@mib.org> wrote:
> Seebs <usenet-nospam@seebs.net> writes:
>> On 2010-02-08, Keith Thompson <kst-u@mib.org> wrote:
>>> The initializer { 0 } sets all members of the initialized object to
>>> zero. This is, or should be, a common C idiom. gcc just doesn't
>>> recognize it.

>>
>> Hmm. I wouldn't have done that; I'd have done { { 0 } } to show that I was
>> aware that I was initializing an aggregate of aggregates.


> Ok. Would you write { { { 0 } } } for an aggregate of aggregates of
> aggregates? And so forth.


By default, yes. I think it's clearer.

> Because the syntax requires at least one initializer between the
> braces, you have to initialize the first element explicitly and leave
> the rest, if any, to be initialized implicitly.


Yup.

> With the "{ }" syntax, you're unambiguously leaving all the members to
> be initialized implicitly (and there'd be nothing for gcc to complain
> about).


Yes, that would be prettier.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
Reply With Quote
  #14 (permalink)  
Old 02-08-2010, 10:24 PM
Ben Bacarisse
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

Keith Thompson <kst-u@mib.org> writes:

> Seebs <usenet-nospam@seebs.net> writes:

<snip>
>> I do agree that it might make sense to special-case the case where there's
>> exactly one initializer, and it's zero.

>
> Right. The point is that { 0 } means, regardless of the depth of the
> object being initialized, that all members and elements are
> initialized to zero (whatever "zero" means for the particular type).
> The object can even be a scalar. And there's no other way to say
> that.
>
> On the other hand, { 0 } also means initializing a single-element
> array or a single-member struct (or a union).


.... or single scalar.

> The rule that allows us to use { 0 } as a generic zero initializer is
> C99 6.7.8p21:
>
> If there are fewer initializers in a brace-enclosed list
> than there are elements or members of an aggregate, or fewer
> characters in a string literal used to initialize an array of
> known size than there are elements in the array, the remainder
> of the aggregate shall be initialized implicitly the same as
> objects that have static storage duration.


[just for completeness...] together with p11 in the same section:

The initializer for a scalar shall be a single expression,
optionally enclosed in braces. [....]

<snip>
> I'd like to see the syntax expanded to allow empty braces:
>
> some_type obj = { };
>
> with the same meaning as:
>
> some_type obj = { 0 };


Nice idea.

<snip>
--
Ben.
Reply With Quote
  #15 (permalink)  
Old 02-08-2010, 10:37 PM
Ben Bacarisse
Guest
 
Posts: n/a
Default Re: Missing braces around {0} initializer?!

Tor Rustad <bwzcab@wvtqvm.vw> writes:
<snip>
> After investigating the gcc man page, I finally (after zillion scrolls):
>
> -Wmissing-braces
> Warn if an aggregate or union initializer is not fully
> bracketed. In the following example, the initializer for a is not
> fully bracketed, but that for b is fully
> bracketed.
>
> int a[2][2] = { 0, 1, 2, 3 };
> int b[2][2] = { { 0, 1 }, { 2, 3 } };
>
> This warning is enabled by -Wall.
>
>
>
> sooo... it appears we need to turn off -Wall, and that's not something
> I will do.


You need only turn off:

-Wno-missing-braces -Wno-missing-field-initializers

and {0} becomes a silent universal initializer. You will still be
warned about excess initializers but, sadly, this:

int primes[5] = { 2, 3, 5, 7 };

will be silent too. I can live with that.

--
Ben.
Reply With Quote
 
Reply

Popular Tags in the Forum
braces, initializer, missing

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
missing braces around initializer Boon Newsgroup comp.lang.c 5 05-13-2009 08:16 PM
Re: newbie: Missing values Gerhard Hellriegel Newsgroup comp.soft-sys.sas 0 03-31-2008 09:55 AM
Re: proc format value assignment oddity - missing values Sigurd Hermansen Newsgroup comp.soft-sys.sas 0 10-30-2005 11:38 PM
Re: Missing Values Jim Groeneveld Newsgroup comp.soft-sys.sas 0 12-08-2004 08:45 AM
Re: Missing values---the simplest code Jim Groeneveld Newsgroup comp.soft-sys.sas 0 12-03-2004 08:35 AM



Language 1 | C | C++ | Php | Python | Lisp | Perl | Ruby | Java | Pascal | Basic | Language 2 | Databases | Oracle | Mysql | Access | Drupal
All times are GMT. The time now is 04:04 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.