1

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

4

0 回答 0