GCC is my favourite compiler, obviously because, its open source, GPL and it builds Linux. I prefer to use -Wall -Wextra -W -Werror options as it captures most of the bugs before in hand.
I have been working on the new XIM (extreme identity matcher) development very recently. I wanted to override the default initialization values that I gave to my struct with a local value - similar to the constructors for local objects in C++.
The code roughly looks like this. I have been working on the new XIM (extreme identity matcher) development very recently. I wanted to override the default initialization values that I gave to my struct with a local value - similar to the constructors for local objects in C++.
#includeThe code compiles well without -W or -Wextra options. Once the extra warning flags are added, GCC starts throwing error:struct A { int x; int y; }; #define A_DEFAULTS .x = 0, .y = 0 int main(void) { struct A a = { A_DEFAULTS, .y = 3 }; printf("a.x: %d a.y: %d\n", a.x, a.y); return 0; }
04:20:38:~/Programs$ gcc 1.c -o 1 -Wall -W -Werror -std=c99 cc1: warnings being treated as errors 1.c: In function ‘main’: 1.c:23:9: error: initialized field overwritten 1.c:23:9: error: (near initialization for ‘a.y’) 04:20:43:~/Programs$Totally weird. I know that this is a valid construct. Since I prefer to use -Werror switch, my code won't even compile and I'm forced to remove the switch. This may be a bug in GCC. I'm not sure. Although it won't break my design, I don't want to assign the values to my structure members after the structure members are initialized. BTW, I'm running Ubuntu 11.04 with GCC 4.5.2.
Update:
Section 6.7.8 of C99 standards clearly mentions the following about initializer list:
The initialization shall occur in initializer list order, each initializer provided for a particular subobject overriding any previously listed initializer for the same subobject; all subobjects that are not initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.I would like to highlight the point here:
Any initializer for the subobject which is overridden and so not used to initialize that subobject might not be evaluated at all.
Any initializer for the subobject which is overridden and so not used to initialize that subobject might not be evaluated at all.
3 comments:
Of course it is technically correct. That's why it's a warning, not an error.
Still, it's very rare that someone would want to initialise the same field in one statement. More often than not, this would probably be a mistake: the programmer might have mistyped a similar name, or simply copied an earlier line and forgotten to change the field name.
Compiler warnings aren't there to stop you from doing things, they're there to catch common programming mistakes and to make sure you know what you're doing.
There are loads of valid constructs that generate perfectly reasonable GCC warnings.
I might add: it is documented:
-Woverride-init (C and Objective-C only)
Warn if an initialized field without side effects is overridden
when using designated initializers.
This warning is included in -Wextra. To get other -Wextra warnings
without this one, use -Wextra -Wno-override-init.
Just use -Wall -Wextra -Werror -Wno-override-init -std=c99 -pedantic and you'll be fine.
Thanks Tom, I'm clear now. Thanks for pointing to the section in GCC manpage. I had the same discussion in the freenode GCC as well.
Post a Comment