栈溢出的处理方式是否有明确的规定?
除了终止进程外,似乎没有太多可以做的。我只是想知道C标准对此有何规定。
栈溢出的处理方式是否有明确的规定?
除了终止进程外,似乎没有太多可以做的。我只是想知道C标准对此有何规定。
标准不要求使用堆栈,并且对于堆栈溢出没有任何说明。
C标准甚至没有定义栈,因此它肯定没有定义当栈溢出时会发生什么。
我相当确定发生的具体情况是由操作系统定义的,但在所有情况下,程序应该退出。您正确地认为一旦发生堆栈溢出(至少作为程序员),您实际上无能为力。您真正能做的就是在第一时间防止它们的发生。
正如其他人所提到的,标准对堆栈并没有任何规定。
但是,我认为如果它要定义堆栈溢出的行为,标准会说这将导致未定义的行为。
::rimshot::
void foo(uintptr_t n)
{
int a;
printf("%p\n", (void *)&a);
if (n+1) foo(n+1);
}
int main()
{
int a;
printf("%p\n", (void *)&a);
foo(0);
}
UINTPTR_MAX
+2个对象a
(在每个调用级别上),它们的寿命都重叠,并且每个对象具有不同的地址。仅通过计数论证是不可能实现这一点的。在某些系统上,确保在堆栈溢出后获得任何可预测的优势会给每个函数调用增加相当大的开销;因此,标准合理地将堆栈溢出视为未定义行为。如果目标是最大化实现可以运行合法程序的效率,这是完全适当的。
标准也不要求系统具有足够的堆栈来支持任何非平凡的函数调用深度。鉴于一些有用的程序(特别是在嵌入式系统领域)可以使用少于16字节的堆栈,并且可能不能节省更多的RAM,要求慷慨的堆栈将违反“不为你不需要的东西付费”的哲学。
不幸的是,由于程序无法说出它将需要什么样的深度,也无法查询可用的堆栈类型,因此唯一可以保证不涉及未定义行为的程序是其堆栈使用低于最小保证的程序;除了嵌入式系统领域外,这基本上意味着标准对于任何大于玩具大小的程序都不保证任何内容。