gpt4 book ai didi

c++ - 默认析构函数 nothrow

转载 作者:IT老高 更新时间:2023-10-28 12:39:25 33 4
gpt4 key购买 nike

以下代码在gcc-4.7.1下不能编译,而是在clang-3.2下编译。哪一个遵循 C++11 标准?

struct X {
virtual ~X() = default;
};

struct Y : X {
virtual ~Y() = default;
};

gcc-4.7.1 提示:

looser throw specifier for 'virtual Y::~Y()'
error: overriding 'virtual X::~X() noexcept(true)'

显然,gcc-4.7.1 认为 X 的默认析构函数不是 nothrow,但 Y 的默认析构函数不是 nothrow。为什么是这样?任何人都可以引用标准中的正确位置吗?谢谢。

我在 stackoverflow 上看到了类似的问题,但没有看到引用标准的答案。

最佳答案

编译器陷入两难境地,原因如下:

(1) 未在函数声明中指定任何异常(即未使用 thrownoexcept(相当于 noexcept(true) )) 表示允许该函数抛出所有可能的异常:

(§15.4/12, emphasis mine) A function with no exception-specification or with an exception-specification of the form noexcept(constant-expression) where the constant-expression yields false allows all exceptions. [...]

(2) 默认析构函数必须完全允许由其隐式定义直接调用的函数所允许的异常:

(§15.4/14, emphasis mine) An implicitly declared special member function (Clause 12) shall have an exception-specification. If f is an implicitly declared default constructor, copy constructor, move constructor, destructor, copy assignment operator, or move assignment operator, its implicit exception-specification specifies the type-id T if and only if T is allowed by the exception-specification of a function directly invoked by f’s implicit definition; f shall allow all exceptions if any function it directly invokes allows all exceptions, and f shall allow no exceptions if every function it directly invokes allows no exceptions.

(3) 当特殊成员(如析构函数)显式默认时,即当你使用=default时,异常规范可选(参见下文“可能”的用法):

(8.4.2/2, emphasis mine) An explicitly-defaulted function [...] may have an explicit exception-specification only if it is compatible (15.4) with the exception-specification on the implicit declaration. [...]

标准中没有声明需要在显式默认析构函数中指定异常。

结论:因此,不指定显式默认析构函数的异常可以有两种解释:

  • 表示允许所有异常(exception)情况(根据上述(1))
  • 或者,或者,意味着与析构函数的隐式默认定义所允许的完全相同的异常被允许(根据上面的(3)),在你的情况下意味着允许没有异常(exception)(根据上面的(2))。

不幸的是,GCC 在基类声明的情况下以一种方式(支持“无异常(exception)”)解决了这个困境,而在派生类的情况下以不同的方式解决了这个困境(支持“所有异常(exception)”那里)。

我相信对这种公认的模棱两可的情况最自然的解释是假设 (2) 和 (3) 覆盖 (1)。 标准没有这么说,但它应该这么说。在这种解释下,Clang 似乎就在这里。

关于c++ - 默认析构函数 nothrow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11497252/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com