有几个特殊函数通常保证不抛出异常,例如:
- 析构函数
交换
方法
考虑以下 swap
实现,如 this answer 中所述:
friend void swap(dumb_array& first, dumb_array& second)
{
using std::swap;
swap(first.mSize, second.mSize);
swap(first.mArray, second.mArray); // What if stack overlow occurs here?
}
它使用两个 swap
函数 - 用于整数和指针。如果第二个函数会导致栈溢出怎么办?对象将被损坏。我猜它不是 std::exception
,它是某种系统异常,比如 Win32-exception
。但是现在我们不能保证不抛出,因为我们正在调用一个函数。
但所有权威来源都只是使用 swap
就好了,这里永远不会抛出异常。为什么?
最佳答案
一般来说,你无法处理堆栈耗尽的问题。该标准没有说明如果堆栈用完会发生什么,也没有说明堆栈是什么,有多少可用等等。操作系统可能会让您在构建可执行文件或运行时控制它,如果您正在编写库代码,所有这些都是无关紧要的,因为您无法控制进程有多少堆栈,或者在用户调用您的库之前已经使用了多少。
您可以假设堆栈溢出导致操作系统在您的程序之外执行某事。一个非常简单的操作系统可能会让它变得奇怪(未定义的行为),一个严肃的操作系统可能会把这个过程搞砸,或者如果你真的不走运,它会抛出一些实现定义的异常。我实际上不知道 Windows 是否为堆栈溢出提供了 SEH 异常,但如果提供了,那么最好不要启用它。
如果您不放心,可以将您的swap
函数标记为noexcept
。然后在一致的实现中,任何试图离开函数的异常都会导致程序terminate()
。也就是说,它以取出你的程序为代价来履行noexcept
契约。
关于c++ - 不抛出异常保证和堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16080419/