P.P*_*.P. 4 c arrays undefined-behavior
C标准定义了许多下限/上限(转换限制),并强制实现应满足每个转换.为什么没有为数组大小定义这样的最小限制?以下程序将编译正常并可能产生运行时错误/段错误,并将调用未定义的行为.
int main()
{
int a[99999999];
int i;
for(i=0;i<99999999;i++)
a[i]=i;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
可能的原因可能是在自动存储上分配了本地数组,它取决于分配的堆栈帧的大小.但为什么不像C定义的其他限制那样达到最小限度?
让我们忘记上面提到的未定义的情况.考虑以下:
int main()
{
int a[10];
int i;
for(i=0;i<10;i++)
a[i]=i;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在上面,是什么让我保证本地数组(尽管非常小)将按预期工作,并且不会因分配失败而导致未定义的行为?
虽然这种小型阵列的分配不太可能在任何现代系统上失败.但是C标准没有定义满足要求,编译器也没有(至少GCC没有)报告分配失败.只有运行时错误/未定义的行为才有可能.困难的部分是没有人能够判断任意大小的数组是否会因分配失败而导致未定义的行为.
请注意,我知道我可以使用动态数组(通过malloc和朋友)来实现此目的,并可以更好地控制分配失败.我更感兴趣的是为什么没有为本地数组定义这样的限制.此外,全局数组将存储在静态存储中,并将增加编译器可以处理的可执行文件大小.
你已经回答了自己的问题; 这是由于堆栈限制.* 即使这可能不起作用:
void foo(void) {
int a;
...
}
Run Code Online (Sandbox Code Playgroud)
如果...实际上是一个递归调用foo.
换句话说,这与数组无关,因为同样的问题会影响所有局部变量.标准无法强制执行要求,因为在实践中,这将转化为无限大小堆栈的要求.
因为语言 C 不应该对可用的堆栈大小施加限制.C在许多(许多)不同的环境中运行.怎么可能得出一个合理的数字呢?地狱,自动存储持续时间!=堆栈,堆栈是一个实现细节.C 语言,没有说"堆栈".
环境决定了这个东西,这是有充分理由的.如果某个环境通过另外的方法实现自动存储持续时间而没有这样的限制怎么办?如果硬件突破并且所有突然的现代机器都不需要这样的限制怎么办?
我们应该在这样的事件中修改标准吗?如果C 语言指定了这样的实现细节,我们将不得不这样做.