Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 是";“太大”;具有自动存储持续时间未定义行为的对象?_C_Language Lawyer - Fatal编程技术网

C 是";“太大”;具有自动存储持续时间未定义行为的对象?

C 是";“太大”;具有自动存储持续时间未定义行为的对象?,c,language-lawyer,C,Language Lawyer,关于“为什么在这个特定情况下在堆栈上分配一个大元素不会失败?”的一系列问题,以及关于“堆栈上的大数组”或“堆栈大小限制”的一系列其他问题,让我搜索标准中记录的相关限制 我知道C标准没有指定“堆栈”,因此它没有为这样的堆栈定义任何限制。但是我想知道在void foo(){char anArray[SIZE_X];…}中,标准能保证程序工作到哪个SIZE_X,如果程序超过这个SIZE_X会发生什么 我找到了以下定义,但我不确定该定义是否真的能保证具有自动存储持续时间的特定支持大小的对象(参见联机C1

关于“为什么在这个特定情况下在堆栈上分配一个大元素不会失败?”的一系列问题,以及关于“堆栈上的大数组”或“堆栈大小限制”的一系列其他问题,让我搜索标准中记录的相关限制

我知道C标准没有指定“堆栈”,因此它没有为这样的堆栈定义任何限制。但是我想知道在
void foo(){char anArray[SIZE_X];…}
中,标准能保证程序工作到哪个
SIZE_X
,如果程序超过这个
SIZE_X
会发生什么

我找到了以下定义,但我不确定该定义是否真的能保证具有自动存储持续时间的特定支持大小的对象(参见联机C11标准草案):

5.2.4.1翻译限制

(1) 实施应至少能够翻译和执行 一个程序,其中包含至少一个 以下限制:

对象中的65535字节(仅在托管环境中)

这是否意味着一个实现必须支持像
void foo(){char anArray[SIZE_X];…}
这样的函数中
SIZE_X
的最大值
65535
,并且
SIZE_X
大于
65535的任何值都是未定义的行为

对于堆,调用
malloc
返回
NULL
让我们控制请求“过大对象”的尝试。但是,如果程序“请求具有自动存储持续时间的过大对象”,特别是如果没有记录这样的最大大小,例如在某些
限制中,我如何控制程序的行为?因此,是否可以编写一个可移植函数,如支持“进入壁垒”的
checkLimits()
,如:


从技术上讲,一个实现只需要翻译和执行一个带有65535字节对象(以及列出的其他内容)的程序,就可以符合标准。它可能会在所有其他方面失败


要知道更大的程序可以工作,您必须依赖具体实现的细节。大多数实现提供的堆栈空间超过64kib,尽管它可能没有文档记录。可能存在用于调整允许的堆栈空间的链接器开关

例如,对于当前macOS上的
ld
链接器,默认值为8 MiB,
-stack\u size
开关可用于设置更多或更少(对于主线程)


我想说的是,既然C标准说环境限制(如堆栈空间)可能会限制实现,那么除了一个特定的示例程序必须工作这一事实之外的任何行为在技术上都是未定义的行为。

这不是堆栈溢出吗?为什么不是未定义的行为呢?我不知道是什么,如果有的话,标准文本要求,但对于记录来说,我遇到的声称符合C99的编译器的最小实际空间只有128字节。问题显然是堆栈溢出,但标准甚至没有提到单词堆栈。也许我们应该要求编译器作者,堆栈溢出程序(如链接问题中的程序)不应该崩溃,因为它们的定义是完美的。
checkLimits
方法的问题是,在很多情况下,它会受到可用内存量的限制。在一个运行多个程序的环境中,其他一些程序可以在调用
checkLimits
和实际调用
foo
之间分配内存“大多数实现提供的堆栈空间超过64kib”-->每年有1亿个嵌入式处理器在不同程度的有限资源下使用C,因此我对“大多数”表示怀疑。@chux:如果你想成为一名技术人员,我认为这些都不是C实现,因为它们都没有记录C标准要求实现记录的所有内容。我相信符合条件的C实现的数量是零,其中51%具有大堆栈。当然,我同意0部分中的51%。
int main() {
   if(! checkLimits()) {
      printf("program execution for sure not supported in this environment.");     
      return 1;
   } else {
      printf("might work. wish you good luck!"); 
   }
   ...
}