2

令人惊讶的是,我发现gcc编译时可以发现这个错误C。我简化了仍然触发警告的代码。我发布了这个问题,以明确它使用的技术的细节。下面是我的文件代码a.c

int main(){
  int a[1]={0};
  return(a[1]);
}

我的 gcc 版本是gcc (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3. 使用时gcc a.c -Wall,没有警告;使用gcc -O1 a.c -Wall时出现警告:

warning: ‘a[1]’ is used uninitialized in this function [-Wuninitialized]

并且在使用gcc -O2 a.c -Wall(或-O3)时,还有另一个警告:

warning: array subscript is above array bounds [-Warray-bounds]

最令人惊讶的是,当我给出a[1]一个值时,上面的编译选项都没有给出任何警告。即使我将索引更改为巨大的数字也没有警告(当然编译后的文件会冒犯操作系统并且会被踢出),

int main(){
  int a[1]={0};
  a[2147483648]=0;
  return(a[2147483648]);
}

我认为上述现象更多的是功能而不是错误。我希望有人帮助我弄清楚会发生什么,和/或为什么编译器是这样设计的。非常感谢!

4

2 回答 2

3

访问数组末尾之后的内存会导致未定义的行为

gcc很好,可以不遗余力地检测并警告您其中一些错误。但是,它没有义务这样做,当然也不能期望它会捕获所有此类错误。

于 2013-08-31T20:50:41.400 回答
3

编译器不需要为此类错误提供诊断,但 gcc 通常能够提供帮助;请注意,这些警告通常部分作为为优化目的而进行的静态分析传递的副产品,这意味着,正如您所注意到的,此类警告通常取决于指定的优化级别。

于 2013-08-31T21:00:12.383 回答