为什么允许在 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
}
指定函数不会抛出可以向非抛出函数的 调用者 承诺他们将永远不需要处理异常。
要么该函数不会抛出异常,要么整个程序将终止。
我很难理解这一点。
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
}
指定函数不会抛出可以向非抛出函数的 调用者 承诺他们将永远不需要处理异常。
要么该函数不会抛出异常,要么整个程序将终止。