为什么编译器不警告越界静态数组索引? [英] Why do compilers not warn about out-of-bounds static array indices?

查看:30
本文介绍了为什么编译器不警告越界静态数组索引?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一个同事最近因为越界写入堆栈上的静态数组而受到严重影响(他在不增加数组大小的情况下向其中添加了一个元素).编译器不应该捕获这种错误吗?即使使用 -Wall -Wextra 选项,以下代码也可以使用 gcc 干净地编译,但它显然是错误的:

A colleague of mine recently got bitten badly by writing out of bounds to a static array on the stack (he added an element to it without increasing the array size). Shouldn't the compiler catch this kind of error? The following code compiles cleanly with gcc, even with the -Wall -Wextra options, and yet it is clearly erroneous:

int main(void)
{
  int a[10];
  a[13] = 3;  // oops, overwrote the return address
  return 0;
}

我肯定这是未定义的行为,尽管目前我找不到 C99 标准的摘录.但在最简单的情况下,数组的大小在编译时已知,索引在编译时已知,编译器至少不应该发出警告吗?

I'm positive that this is undefined behavior, although I can't find an excerpt from the C99 standard saying so at the moment. But in the simplest case, where the size of an array is known as compile time and the indices are known at compile time, shouldn't the compiler emit a warning at the very least?

推荐答案

GCC 确实 对此提出警告.但是你需要做两件事:

GCC does warn about this. But you need to do two things:

  1. 启用优化.至少没有 -O2,GCC 就没有做足够的分析来了解 a 是什么,以及你跑偏了.
  2. 更改您的示例,以便实际使用 a[],否则 GCC 会生成一个无操作程序并完全放弃您的分配.
  1. Enable optimization. Without at least -O2, GCC is not doing enough analysis to know what a is, and that you ran off the edge.
  2. Change your example so that a[] is actually used, otherwise GCC generates a no-op program and has completely discarded your assignment.

.

$ cat foo.c 
int main(void)
{
  int a[10];
  a[13] = 3;  // oops, overwrote the return address
  return a[1];
}
$ gcc -Wall -Wextra  -O2 -c foo.c 
foo.c: In function ‘main’:
foo.c:4: warning: array subscript is above array bounds

顺便说一句:如果您在测试程序中返回了 [13],那也不起作用,因为 GCC 再次优化了数组.

BTW: If you returned a[13] in your test program, that wouldn't work either, as GCC optimizes out the array again.

这篇关于为什么编译器不警告越界静态数组索引?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆