这在VC9的警告级别4没有警告编译.为什么不认为这是编译器缺陷?

pga*_*ast 4 c++ visual-c++-2008

我看到一些发布的代码超出范围错误,这让我很奇怪.我希望编译器为此代码生成警告(至少在最高级别)

#pragma warning(push,4)
int main(){
    int x[2];
    x[2]=0;     
    return 0;
}
#pragma warning(pop)
Run Code Online (Sandbox Code Playgroud)

但事实并非如此.

EDG编译器很好地说:

"sourceFile.cpp", line 3: warning:
          subscript out of range
          x[2]=0;
          ^
Run Code Online (Sandbox Code Playgroud)

实际上EDG说的更多(所有这些都是预期的)

"sourceFile.cpp", line 1: warning: 
          unrecognized #pragma
  #pragma warning(push,4)
          ^

"sourceFile.cpp", line 4: warning: 
          subscript out of range
      x[2]=0;     
      ^

"sourceFile.cpp", line 3: warning: 
          variable "x" was set but never used
      int x[2];
          ^

"sourceFile.cpp", line 7: warning: 
          unrecognized #pragma
  #pragma warning(pop)
Run Code Online (Sandbox Code Playgroud)

但这不是我的问题.

我认为这个失败警告VC9中遗漏的严重错误,(因为自动变量!!!!).任何人都可以给我一个改变主意的严肃理由吗?

Dig*_*oss 17

许多编译器都有选择错误地解决这类问题.

但是对于C编译器来说,它是非常传统的,甚至适用于默认情况下.这有多种原因.

  1. 请记住,x[i]并且i[x]是在C同样的事情你甚至可以做"string"[2]或者可以做的2["string"],并得到了相同的结果.试试吧.这是因为x[i]定义为*(x + i),一旦C只是做指针运算,然后解析表达式的结果,它不在编译器的域中,以决定它是否会起作用.

  2. 鉴于指针算法是合法的,许多相当不错的设计模式实际上取决于技术下标违规

    struct s {
        ...bunch of stuff...
        int points[1]; // not really [1]
    };
    ...
    struct s *p = malloc(sizeof (struct s) + someNumber * sizeof(int));
    

    今天有这样的代码运行到处...     更新:呵呵,这是stackoverflow上的struct hack的一个实际例子.

  • 凉.但它仍然是一个很好的问题,未来的访问者将找到自己的方式. (2认同)

180*_*ION 8

编译器不需要发出未定义行为的警告(即使是"严重"的行为).许多编译器都有不同的行为,他们倾向于检查.我认为如果你有VSTS,可以启用一些额外的安全检查,这样就可以捕获它.此外,编译器可以插入将捕获此内存覆盖的运行时检查(可能用于调试版本),因此您应确保已启用这些内存.

  • @Dan Molding:编译器需要在某些情况下进行诊断.错误和警告都是诊断; 区别在于编译器是否仍然决定创建输出. (3认同)
  • 它不依赖于编译器,它是未定义的行为 - 你知道它的区别吗? (2认同)

dmc*_*kee 7

虽然给出的示例非常简单,但是在编译期间做好静态分析通常需要相当多的代码并减慢编译速度(一个简单的实现意味着另一个通过AST的过程).

在一种已经经常被指责用于缓慢编译的语言中.

让你变得愚蠢是c ++的重要组成部分.试图拯救你自己的编译器很好,但这很有道理.

FWIW:g++ -Wall也没有警告.


Fra*_*nov 5

在对源执行静态代码分析时会发出此警告.然而,静态代码分析不是编译器规范的一部分(至少据我所知),并且由一个单独的工具完成.

以下是C/C++代码分析的概述.以及该工具涵盖的警告列表.