I am following the book "C Primer Plus" and encounter such a snippet of code:
// designate.c -- use designated initializers
#include <stdio.h>
#define MONTHS 12
int main(void)
{
int days[MONTHS] = {31, 28, [4] = 31, 30, 31, [1] = 29};
int i;
for (i = 0; i < MONTHS; i++)
printf("%2d %d\n", i+1, days[i]);
return 0;
}
It reports errors when I compiled it:
$ cc designate.c
designate.c:6:57: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides]
int days[MONTHS] = {31, 28, [4] = 31, 30, 31, [1] = 29};
^~
designate.c:6:29: note: previous initialization is here
int days[MONTHS] = {31, 28, [4] = 31, 30, 31, [1] = 29};
^~
1 warning generated.
Nonetheless, ./a.out
works properly.
$ ./a.out
1 31
2 29
3 0
4 0
5 31
6 30
7 31
8 0
9 0
10 0
11 0
12 0
I am very confused here about what should I learn from the error report?
While it is true that the warnings are often about serious issues, this one just says that something that you do doesn't make much sense and could be an oversight. Specifically
int days[MONTHS] = {31, 28, [4] = 31, 30, 31, [1] = 29};
Here you're having 28
for element 1, and then you're overwriting it to 29
with [1] = 29
. So that 28
is gone, and that's what it warns you about. It translates to this:
int days[MONTHS] = {31, 29, 0, 0, 31, 30, 31};
And as you can see from your results:
1 31
2 29
3 0
4 0
5 31
6 30
The 28
indeed is gone. The compiler doesn't know how important that 28
was to you, perhaps it was very important and [1] = 29
was a typo. That's why it warns you. And as you can also see, there's some whackiness with March and April having 0
days going on, surely this isn't what you intended.