gcc编译器报告警告,但a.out可以正常运行

时间:2018-10-16 10:09:52

标签: c

我正在阅读《 C Primer Plus》这本书,并且遇到了如下代码片段:

// 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;
}

编译时会报告错误:

$ 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.

尽管如此,./a.out仍然可以正常工作。

$ ./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

我很困惑我应该从错误报告中学到什么?

2 个答案:

答案 0 :(得分:5)

虽然警告的确经常与严重问题有关,但该警告仅表示您所做的事情没有多大意义,可能是疏忽大意。专门

int days[MONTHS] = {31, 28, [4] = 31, 30, 31, [1] = 29};

这里,元素1具有28,然后用29将其覆盖到[1] = 29。这样28消失了,这就是警告您的地方。转换为:

int days[MONTHS] = {31, 29, 0, 0, 31, 30, 31};

从结果中可以看出:

1 31
2 29
3 0
4 0
5 31
6 30

28确实消失了。编译器不知道28对您来说有多重要,也许这很重要,而[1] = 29是一个错字。这就是为什么它警告您。正如您还看到的那样,三月和四月的0天持续进行着,有些怪异,这肯定不是您想要的。

答案 1 :(得分:0)

好吧,您设置arr [0] = 31,arr [1] = 28,arr [4] = 31,依此类推。设置[1] = 29时,将var重置为arr [1],即28到29。