我正在研究说明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
?