简体   繁体   English

C++ 标准对堆栈溢出有何规定?

[英]What does the C++ standard say about stack overflow?

I took a look at the draft C++0x standard, and as far as I can tell there is nothing about stack overflow in there.我查看了 C++0x 标准草案,据我所知,那里没有任何关于堆栈溢出的内容。 Searching for "stack overflow" yields no results, and searching for "stack" I've only gotten references to stack unwinding and std::stack.搜索“堆栈溢出”没有结果,搜索“堆栈”我只得到了对堆栈展开和 std::stack 的引用。 Does that mean that there cannot be a conforming implementation of the C++ standard, since there is no mechanism allowed for handling the error when memory is exhausted by a local object such as a huge local array?这是否意味着不能有符合 C++ 标准的实现,因为当 memory 被本地 object 耗尽时,没有允许处理错误的机制?

The answers to this question indicate that at least the C standard does not mention stack overflow. 这个问题的答案表明,至少 C 标准没有提到堆栈溢出。

To make the question concrete, consider this program为了使问题具体化,请考虑这个程序

// Program A
int identity(int a) {
  if (a == 0)
    return 0;
  char hugeArray[1024 * 1024 * 1024]; // 1 GB
  return identity(a - 1) + 1;
}
int main() {
  return f(1024 * 1024 * 1024);
}

and this program和这个程序

// program B
int main() {
  return 1024 * 1024 * 1024;
}

I think the C++ standard does not allow any C++ implementation to do something observably different on these two programs.我认为 C++ 标准不允许任何 C++ 实现在这两个程序上做一些明显不同的事情。 In reality program A won't run on any modern machine as it is allocating an exabyte of memory on the stack (imagine the function actually used the huge array so the compiler can't silently remove it to no ill effect).实际上,程序 A 不会在任何现代机器上运行,因为它在堆栈上分配了 EB 的 memory(想象一下 function 实际上使用了巨大的数组,因此编译器无法静默地将其删除而不会产生不良影响)。 Does the C++ standard allow program A to fail? C++ 标准是否允许程序 A 失败?

Edit: The question is not whether the standard should define what happens on stack overflow, the question is what it says, if anything.编辑:问题不在于标准是否应该定义堆栈溢出时会发生什么,问题是它说了什么,如果有的话。

I'm not sure if this is what you're looking for, but in Appendix B of the C++03 ISO standard there's the following notice:我不确定这是否是您要查找的内容,但在 C++03 ISO 标准的附录 B 中有以下通知:

  1. Because computers are finite, C++ implementations are inevitably limited in the size of the programs they can successfully process.由于计算机是有限的,C++ 实现不可避免地受限于它们可以成功处理的程序的大小。 Every implementation shall document those limitations where known.每个实施都应在已知的情况下记录这些限制。 This documentation may cite fixed limits where they exist, say how to compute variable limits as a function of available resources , or say that fixed limits do not exist or are unknown.本文档可能会引用存在的固定限制,例如如何将可变限制计算为可用资源的 function ,或者说固定限制不存在或未知。
  2. The limits may constrain quantities that include those described below or others.这些限制可能会限制包括以下描述的数量或其他数量。

(My emphasis) I take this to mean it is perfectly legal for the compiler to allow one of those functions to work while failing another, provided that the compiler states what limitations are in place and how they are computed from the resources the system has available. (我的重点)我认为这意味着编译器允许其中一个函数在另一个函数失败时工作是完全合法的,只要编译器说明存在哪些限制以及如何从系统可用的资源中计算它们.

Behavior is undefined because the Standard does not define what happens with a program that exceeds resource limits.行为未定义,因为标准没有定义超出资源限制的程序会发生什么。 Note that there are recommended limits in Annex B of the spec.请注意,规范的附录 B 中有推荐的限制。 That annex is non-normative though and an implementation can ignore that annex, including having different limits than specified there.尽管该附件是非规范性的,但实施可以忽略该附件,包括具有与此处指定不同的限制。 In 1.4 [intro.compliance], the spec says在 1.4 [intro.compliance] 中,规范说

If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its resource limits, accept and correctly execute that program.如果程序不违反本国际标准中的规则,则符合要求的实现应在其资源限制内接受并正确执行该程序。

There is nothing that says what shall happen with a program that contains no violation of the rules in the IS but that can't be accepted and correctly executed within the resource limits of the implementation.没有什么可以说明不违反 IS 规则但不能在实现的资源限制内被接受和正确执行的程序会发生什么。 Hence behavior is undefined for such a case.因此,对于这种情况,行为是未定义的。

A stack overflow is breaking the protection mechanism that the operating system has in place.堆栈溢出正在破坏操作系统已有的保护机制。 It is not a feature of the language as all machine executable code will have this same protection.它不是该语言的特性,因为所有机器可执行代码都将具有相同的保护。

If you want to catch this particular error, you'll need to write operating system specific code.如果你想捕捉这个特定的错误,你需要编写操作系统特定的代码。 On Linux, for example, you'll need to catch a SIGSEGV (segmentation fault) signal.例如,在 Linux 上,您需要捕获 SIGSEGV(分段错误)信号。 However, note that this could also be raised by a NULL pointer deference, or any other memory protection issues, not just stack overflow.但是,请注意,这也可能由 NULL 指针引用或任何其他 memory 保护问题引起,而不仅仅是堆栈溢出。

Not sure about Windows, OSX or mobile devices.不确定 Windows、OSX 或移动设备。

What happens on stack overflow is extremely system-dependent (both CPU and OS, and sometimes compiler because it's up to the compiler to insert stack probes and other mechanisms for safely extending the stack), so it's impossible to mandate a particular response;堆栈溢出时发生的情况非常依赖于系统(CPU 和操作系统,有时还有编译器,因为由编译器插入堆栈探测器和其他安全扩展堆栈的机制),因此不可能强制执行特定响应; the best that could be done would be to suggest responses that would be preferable if the target platform allows it.如果目标平台允许,最好的办法是提出更可取的回应。 Most don't;大多数没有; while there is a reasonable way to handle heap overflow, a stack overflow handler (a) is likely to be invoked when the stack is in an inconsistent state, with a partially constructed stack frame on it, and (b) is likely to involve invoking a handler... which requires stack space for the interrupt frame.虽然有一种合理的方法来处理堆溢出,但堆栈溢出处理程序 (a) 可能会在堆栈位于不一致的 state 中时被调用,并且上面有部分构造的堆栈帧,并且 (b) 可能涉及调用一个处理程序......它需要用于中断帧的堆栈空间。 POSIX specifies a sigaltstack() mechanism, but it too has restrictions, and ANSI C C/C++ can't reasonably depend on POSIX compliance. POSIX 指定了sigaltstack()机制,但它也有限制,并且 ANSI C C/C++ 不能合理地依赖于 POSIX 合规性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C ++语言标准对static_cast如何处理减小整数大小有何看法? - What does the C++ language standard say about how static_cast handles reducing the size of an integer? 关于移动活动对象存储,C ++标准怎么说? - What does C++ standard say about moving live object storage? 关于使用noexcept覆盖throw()函数,C ++标准有何说法? - What does the C++ standard say about overriding a throw() function with noexcept? C ++标准对于在目标类型范围之外的类型的转换结果的结果有何评价? - What does the C++ standard say about results of casting value of a type that lies outside the range of the target type? 数字和字段宽度的格式化输出,C ++标准对此有何说明? - formatted output of a number and field width, where does the C++ standard say about it? C++20 标准对使用子对象作为模板非类型 arguments 有什么看法? - What does the C++20 standard say about usage of subojects as template non-type arguments? C ++标准对std :: vector的评价是什么 <int> V1,V2; 性病::距离(v1.begin(),v2.begin())? - What does the C++ standard say about std::vector<int> v1,v2; std::distance(v1.begin(),v2.begin())? 标准对作为模板参数的 char 数组有何看法? - What does the standard say about char arrays as template arguments? 标准对未对齐的内存访问有何看法? - What does the standard say about unaligned memory access? 标准对lambda类型的命名空间有何看法? - What does the Standard say about the namespace of lambda types?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM