☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

析构函数不可抛出异常

7.8 ID_throwInDestructor
目录 › next › previous

析构函数抛出异常会违反异常处理机制。

抛出异常后,从 throw 表达式到相应 catch 子句各层调用栈中的对象会被自动析构,如果这个过程中某个对象的析构函数抛出异常便违反了异常处理机制,这种情况将直接引发 std::terminate 函数的执行,所以从析构函数抛出的异常可能无法被捕获和处理,也可能导致程序异常终止。

示例(设 E0 和 E1 是不相关的异常类):

class A {
    ....
public:
   ~A() try {
        if (cond0) {
            throw E0();    // Non-compliant, propagate out
        }
        else if (cond1) {
            throw E1();    // OK, digested by itself
        }
    }
    catch (const E1&) {
        ....
    }
};

建议将析构函数声明为 noexcept。

与析构相关的过程也不应抛出异常:

  • 资源回收
  • delete、delete[] 运算符
  • 具有 deallocate、free 等语义的函数

另外,具有 swap、hash 等语义以及移动构造、移动赋值相关的过程也不应抛出异常,详见相关规则。

相关

ID_throwInDelete ID_throwInHash ID_throwInSwap ID_throwInMove

依据

ISO/IEC 14882:2003 15.2(3) ISO/IEC 14882:2011 3.7.4.2(3)-undefined ISO/IEC 14882:2011 15.2(3)

参考

C++ Core Guidelines C.36 C++ Core Guidelines C.37 MISRA C++ 2008 15-5-1 SEI CERT DCL57-CPP
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.