【发布时间】:2013-01-19 15:43:23
【问题描述】:
C 标准定义了许多下限/上限 (translation limits),并规定了每个翻译都应满足的实现。为什么没有为数组大小定义这样的最小限制?以下程序可以正常编译,并可能产生运行时错误/段错误,并会调用 未定义行为。
int main()
{
int a[99999999];
int i;
for(i=0;i<99999999;i++)
a[i]=i;
return 0;
}
一个可能的原因可能是在自动存储上分配了本地数组,这取决于分配的堆栈帧的大小。但是为什么不像 C 定义的其他限制那样设置最小限制呢?
让我们忘记上面的未定义情况。考虑以下几点:
int main()
{
int a[10];
int i;
for(i=0;i<10;i++)
a[i]=i;
return 0;
}
在上面,是什么让我保证本地数组(尽管非常小)会按预期工作并且不会由于分配失败而导致未定义的行为?
尽管在任何现代系统上分配如此小的阵列都不太可能失败。但是 C 标准没有定义任何要满足的要求,并且编译器不会(至少 GCC 不会)报告分配失败。只有运行时错误/未定义的行为是可能的。 困难的部分是没有人知道任意大小的数组是否会由于分配失败而导致未定义的行为。
请注意,我知道我可以为此目的使用动态数组(通过 malloc 和朋友),并且可以更好地控制分配失败。我更感兴趣的是为什么没有为本地数组定义这样的限制。此外,全局数组将存储在静态存储中,并将增加编译器可以处理的可执行文件大小。
【问题讨论】:
-
“困难的部分是没有人知道任意大小的数组是否会由于分配失败而导致未定义的行为。” - 你建议如何解决这个问题?你会使用什么最小值?请记住 C 运行的平台种类繁多,从带有少量堆栈的微型微控制器到带有非常大堆栈的 64 位以上架构,应有尽有。此外,递归会极大地影响堆栈的可用性。如果您使用 C 进行编程,您通常会了解您的硬件,从而了解您的堆栈可用性。
-
@KingsIndian 我认为解决方案是避免在可能对其施加意外压力的情况下使用“堆栈” - 并了解执行要求的限制。这有点像过多的递归:它会在某些环境中比其他环境更快地产生 UB。
-
@KingsIndian 写得很好。我试图想一个更好的标题,但你的最后一段消除了这样的焦点:) 希望它会保持开放,因为我认为有很好的信息和响应。
标签: c arrays undefined-behavior