首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >默认析构函数nothrow

默认析构函数nothrow
EN

Stack Overflow用户
提问于 2012-07-16 09:50:46
回答 1查看 4K关注 0票数 33

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

代码语言:javascript
复制
struct X {
  virtual ~X() = default;
};

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

gcc-4.7.1抱怨说:

代码语言:javascript
复制
looser throw specifier for 'virtual Y::~Y()'
error: overriding 'virtual X::~X() noexcept(true)'

显然,gcc-4.7.1认为X的默认析构函数为nothrow,但Y的默认析构函数不是nothrow。为什么会这样呢?有人能在标准中找到正确的位置吗?谢谢。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-16 11:27:51

由于以下原因,编译器在中陷入了困境:

(1)在函数声明中不指定任何异常(即,不使用thrownoexcept (相当于noexcept(true) ))意味着允许该函数抛出所有可能的异常

(§15.4/12,重点是我的)一个函数,它具有无异常特定的阳离子或具有noexcept(constant-expression)形式的异常特定的阳离子,其中constant-expression产生false 允许所有异常。 ...

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

(§15.4/14,重点是我的)隐式声明的特殊成员函数(第12条)应具有特定于例外的fi阳离子。如果f是一个隐式声明的默认构造函数,复制构造函数,移动构造函数,析构函数,复制赋值运算符,或移动赋值运算符,则它的隐式异常指定类型规范当且仅当T是由f的隐式definition直接调用的函数的异常规范允许时;f将允许所有异常,如果它直接调用的任何函数允许所有异常,并且如果它直接调用的每个函数都不允许任何异常,则f将不允许任何异常。

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

(8.4.2/2,强调我的)显式默认的函数 ... 只有当它与隐式声明上的异常特定fi阳离子兼容(15.4)时,它才可能具有显式异常特定fi阳离子。..。

标准中没有要求在显式默认的析构函数中指定异常规范的语句。

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

  • 表示允许所有异常(根据上面的(1) )
  • ,或者,替代地,表示允许与析构函数的隐式默认定义(根据上面的(3) )所允许的完全相同的异常,在您的情况下意味着不允许任何异常(根据上面的(2) )。

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

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

票数 37
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11497252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档