【发布时间】:2018-04-23 01:03:09
【问题描述】:
关于 SO 的 recent question 关于“为什么在这种特定情况下在堆栈上分配大元素不会失败?”以及一系列有关“堆栈上的大型数组”或“堆栈大小限制”的其他问题让我搜索了标准中记录的相关限制。
我知道 C 标准没有指定“堆栈”,因此它没有为这种堆栈定义任何限制。但我想知道void foo() { char anArray[SIZE_X]; ... } 中的哪个SIZE_X 标准保证程序可以工作,如果程序超过这个SIZE_X 会发生什么。
我找到了以下定义,但我不确定这个定义是否真的是对具有自动存储持续时间的特定支持大小的对象的保证(参见this在线C11标准草案):
5.2.4.1 翻译限制
(1) 实现应至少能够翻译和执行 一个程序,其中至少包含一个实例 以下限制:
...
对象中的 65535 字节(仅在托管环境中)
这是否意味着实现必须支持在 void foo() { char anArray[SIZE_X]; ... } 之类的函数中对 SIZE_X 的值最大为 65535,并且对于 SIZE_X 的任何大于 65535 的值都是未定义的行为?
对于堆,调用malloc 返回NULL 让我控制请求“太大对象”的尝试。但是,如果程序“请求具有自动存储持续时间的太大对象”,特别是如果没有记录这样的最大大小,我该如何控制程序的行为,例如在一些limits.h?那么是否可以编写像checkLimits() 这样的可移植函数来支持“进入障碍”,例如:
int main() {
if(! checkLimits()) {
printf("program execution for sure not supported in this environment.");
return 1;
} else {
printf("might work. wish you good luck!");
}
...
}
【问题讨论】:
-
不会是堆栈溢出吧?
-
为什么不是未定义的行为?
-
我不知道标准文本需要什么,但作为记录,我遇到的编译器声称符合 C99 的最小实际空间只是不到 128 个字节。
-
问题显然是堆栈溢出,但标准甚至没有提到堆栈这个词。也许我们应该向编译器作者提出要求,堆栈溢出程序(例如链接问题中的程序)不应该崩溃,因为它们已被完美定义。
-
checkLimits这样的方法的问题在于,在很多情况下,它会受到可用内存量的限制。在运行多个程序的环境中,其他程序可以在您调用checkLimits和实际调用foo之间分配内存。
标签: c language-lawyer