以下代码不能在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上看到了类似的问题,但我没有看到涉及标准的答案。
发布于 2012-07-16 11:27:51
由于以下原因,编译器在中陷入了困境:
(1)在函数声明中不指定任何异常(即,不使用throw或noexcept (相当于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阳离子。..。
标准中没有要求在显式默认的析构函数中指定异常规范的语句。
结论:因此,没有指定显式默认析构函数的异常的可以用两种方式解释:
不幸的是,在基类声明的情况下,GCC以一种方式(支持“无异常”)解决了这个难题,而在派生类的情况下,以一种不同的方式(支持“所有异常”)。
我认为,对于这种公认的模棱两可的情况,最自然的解释是假设(2)和(3)覆盖(1)。标准没有这样说,但它应该这样说。根据这种解释,Clang似乎就在这里。
https://stackoverflow.com/questions/11497252
复制相似问题