我正在研究noexcept
说明符,我想知道它的一些设计决策背后的原因。特别是,它没有进行相同的编译时检查,例如,constexpr
说明符。我稍后会解释这个断言。
这是我正在测试的代码:
#include <iostream>
#include <stdexcept>
void g()
{
throw std::runtime_error("EXCEPT");
}
void f() noexcept
{
g();
}
int main()
{
try
{
f();
}
catch(const std::exception & e)
{
std::cout << "Caught this: " << e.what() << std::endl;
}
return 0;
}
这个版本的代码编译但崩溃了,因为(如果我理解的话)使用noexcept
说明符,编译器只是“信任我”并进行了优化,不允许代码在运行时处理任何异常,尽管try
/ catch
阻止。
我不明白的是:为什么编译器不检查像g()
的签名这样的简单事情? g()
尚未声明为noexcept
,因此如果不进行昂贵的检查,是否真的抛出,代码应该被视为错误,因为g()
隐含地noexcept(false)
。在哪种情况下这有用吗?
为了按照我个人的预期工作,我必须像这样更改f()
的签名:
void f() noexcept(noexcept(g()))
{
g();
}
现在,noexcept
声明中的f()
说明符仅在g()
声明中出现时才会应用。在运行时,异常处理得很好。为什么这不是默认值?如果f()
调用了很多函数,那么手动执行每个被调用函数的noexcept(noexcept(g()))
就是维护地狱。
我引用了constexpr
说明符,因为它实际上使编译器检查constexpr
函数调用的所有函数本身都声明为constexpr
。所以,我认为noexcept
不这样做的原因与编译时间有关。
总结问题:为什么编译器不会检查noexcept
函数调用的函数本身是否被声明为noexcept
?