为什么允许在noexcept-tagged函数中抛出异常?

时间:2016-04-04 01:10:16

标签: c++ exception compilation tags noexcept

我很难理解这一点。

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

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

2 个答案:

答案 0 :(得分:6)

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

至于为什么允许这样做,根本无法彻底检查是否有违反规范的内容。考虑类似的事情:

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

可以f投掷吗?不能说。

答案 1 :(得分:3)

声称不扔的功能实际上可能会抛出 如果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
}

指定一个函数不会向非投掷函数的调用者提出承诺,他们永远不需要处理异常。

函数不会抛出或整个程序将终止。