为什么这不会产生分段错误

mav*_*k30 -1 c++

这是c ++中的for循环.我不明白为什么它不会在执行时给出分段错误.

int main() 
{
   int arr[5];
   for (int x = 0; x <= 5; x++)
       {
           arr[x] = x;
       }
   return 0; 
}
Run Code Online (Sandbox Code Playgroud)

And*_*owl 18

这是未定义的行为.未定义的行为意味着任何事情都可能发生,包括:

  • 分段故障
  • 完全没有错误
  • 输出不一致
  • 格式化硬盘
  • ... (随你)

为了更正式一点,这就是C++ 11标准定义未定义行为的方式:

本国际标准没有要求的行为[ 注意:当本国际标准忽略任何明确的行为定义或程序使用错误的结构或错误数据时,可能会出现未定义的行为.允许的未定义行为包括完全忽略不可预测的结果,在翻译或程序执行期间以环境特征(有或没有发出诊断消息)的特定行为,终止翻译或执行(发布时)一条诊断信息).许多错误的程序结构不会产生未定义的行为; 他们需要被诊断出来. - 尾注]

关于为什么做x[5]的确是未定义的行为,那是因为x[5]等同于*(x + 5)(见第8.3.4/6段),关于一元运算符的第5.3.1/1段*规定:

一元*运算符执行间接:它所应用的表达式应该是指向对象类型的指针,或指向函数类型的指针,结果是指向表达式指向的对象或函数的左值.如果表达式的类型是"指向T的指针",则结果的类型为"T".[...]

但由于x + 5没有指向任何对象,并且上面的段落没有指定取消引用此类指针的结果应该是什么,之前引用的句子适用:

[...]当本国际标准忽略任何明确的行为定义时,可能会出现未定义的行为[...]

这意味着这x[5]是未定义的行为.

  • 需要有一个C++编译器,它可以检测到未定义的行为,并且实际上可以格式化硬盘驱动器.危险的编码. (4认同)
  • @someguy,因为它允许编译器执行某些优化. (2认同)