gcc exception specification of default destructor

旧街凉风 提交于 2019-12-09 15:57:12

问题


class A
{
    public:
    virtual ~A()
    {
    }
};

class B : virtual public A
{
    public:
    ~B() throw()
    {}
};

class C : public B
{
};

int main(int argc, char * argv [])
{
return 0;
}

That code gives the following error:

error: looser throw specifier for ‘virtual C::~C()’
error:   overriding ‘virtual B::~B() throw ()’

on my debian testing ( gcc (Debian 4.6.0-10) 4.6.1 20110526 (prerelease) ) but compiles without errors on previous gcc versions ( 4.5 on my debian system again).

How does an exception specification affect virtual destructor overriding? According to that answer the compiler is supposed to create a default constructor matching the throw declaration of the base class. Obviously this is not what happens on new gcc. What has changed, what is the correct compiler behavior and is there some easy solution to the problem other than manually adding empty destructors in derived classes ( compiler flag for example).


回答1:


I presume that in the real code either ~A() or ~B() is declared virtual? (The error message is complaining about a virtual destructor, but in the code as written none of the destructors are virtual.)

I believe the virtual inheritance is what is triggering your problem. C's (implicitly defined) destructor is required to first call ~B() and then, because C is the most-derived class, to call ~A(). (12.4/6)

The generated exception specification for ~C() is required to allow any exception to propagate, because it directly calls ~A() which has no exception specification. (15.4/13)

And that then triggers your error - you can't override a virtual function with a throw() specification (B's destructor) with a version that may throw. (15.4/3)

The solution would be to put throw() on A's destructor. (If you can't do that, then why are you doing it on B's?)

The error also wouldn't happen without the virtual inheritance - because then C's destructor would only call B's destructor. (B's destructor would still call A's - and you're still skating on thin ice, because if A's destructor throws you're going straight to terminate().)




回答2:


GCC 4.X is stricter than previous versions, and therefore may not state it implicitly. Try stating it explicitly.

The way I understand it, if class B had a destructor which explicitly threw nothing (ie.

class B: public A
{
public:
virtual ~B() throw { }
}

It should be ok.

Regardless, last time I checked it was very poor practice to throw exceptions from d'tors.

Hope that helps ya some!



来源:https://stackoverflow.com/questions/6539009/gcc-exception-specification-of-default-destructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!