为什么允许在 noexcept 标记的函数中抛出异常?

Why is it allowed to throw an exception inside a noexcept-tagged function?

我很难理解这一点。

double compute(double x, double y) noexcept
{
   if (y == 0)
       throw std::domain_error("y is zero");
   return x / y;
}

这在 clang 中编译得很好(我没有检查 gcc),但对我来说这似乎是胡说八道。为什么编译器会允许 noexcept 函数包含 throw 语句?

std::terminate() 会被触发,因为您的异常规范不允许发生这种情况(请参阅 [except.spec/9])。

至于为什么允许这样做,根本不可能详尽地检查是否有任何违反规范的地方。考虑这样的事情:

double f(double );
double compute(double x, double y) noexcept
{
    return x / f(y);
} 

可以f扔吗?不能说。

有可能声称不抛出的函数实际上会抛出。
如果 noexcept 函数 确实 抛出,则调用 terminate,从而强制承诺不在 运行 时间抛出。

// The compiler does not check the `noexcept` specification at compile time.
void f() noexcept // Promises to not throw any exception
{
    throw runtime_error("error"); // Violates the exception specification
}

指定函数不会抛出可以向非抛出函数的 调用者 承诺他们将永远不需要处理异常。

要么该函数不会抛出异常,要么整个程序将终止。