如果一个 try-catch 块被证明是非抛出的,编译器必须总是删除它

Must a compiler always remove a try-catch block if it's proven to be non-throwing

考虑一下:

#include <stdexcept>

template <class T>
void F(T &&t) {
    try {
        t(); 
    } catch(...) {}
}

int main() {
    F([]() noexcept {});             // Call 1
    F([]{});                         // Call 2
    F([]{ throw std::exception{}; });// Call 3
}

我在 clang++-6.0 上发现带有标志 -std=c++17,不管我给出的优化标志如何,总是没有 __gxx_personalityCall 1 的任何异常处理代码。

使用不同的编译器时可以依赖这样的优化吗?我只考虑C++11及以上

noexcept 说明符被添加到 c++11 作为 throw() 的替代。它保证函数不会抛出。它与 throw() 的区别在于,对于 noexcept,如果函数 实际上抛出 ,则堆栈 仅可能被展开 ,前者不是这种情况(堆栈总是展开)。这样可以实现更多优化,例如完全省略异常处理。

总而言之,由编译器决定是否省略异常处理,但是对于 noexcept没有理由不这样做,这确实其他情况下很难确定。