Conflicting type attributes specified for virtual destructor

懵懂的女人 提交于 2020-01-05 01:52:34

问题


The following extract was previously compiling under Borland C++, MSVC and OpenWatcom:

class aaa {
    virtual _fastcall ~aaa();
};

class bbb:public aaa {
};

It doesn't compile under gcc/g++ (MinGW 4.8.0). Error:

probz.cpp:7:7: error: conflicting type attributes specified for 'virtual bbb::~bbb()'
 class bbb:public aaa {
       ^
probz.cpp:3:20: error:   overriding 'virtual aaa::~aaa()'
   virtual _fastcall ~aaa()=0;///can't be abstract
                     ^

Obviously, there is no bbb::~bbb()!

EDIT

The actual class hierarchy is bigger, there are many classes bbb inheriting from aaa, and there are intermediate members in between, i.e. bbb extends abb, which extends aab, which extends aaa. aaa indeed has an abstract virtual destructor, which gets implementation in the intermediate classes, but not in the leaves. Yes, I can remove the __fastcall attribute and it compiles. Is it a gcc limitation that I cannot adjust the calling convention?


回答1:


The __fastcall is a calling convention.

It's a non standard feature : the double underscore at the begin of the name means that it's implementation specific. Calling conventions are tightly related to the systems and CPU architectures. This one seems to be relevant for x86 32 bit mode.

Some recommendations:

  • You shouldn't bother with calling conventions unless absolutely required (e.g.when interfacing with precompiled libraries or extern dlls).
  • The level of optimizing that modern compilers perform does no longuer require such manual tuning. The same applies with keyword register
  • If your code really needs it on some platforms, you should foresee a #define in one of your header and make sure with conditional compilation that it's defined to nothing on platform/compilers where it's not relevant (for DLLs this approach is usual, with a library specific #define).
  • Calling conventions should be the same in all the derived classes, so it's better declared in the base class. For virtual functions this is an implicitely mandatory requirement ! Imagine that your base class passes parameters via the stack, and the derived class via the registers (fastcall). Now what code should your compiler generate if you make a polymorphic call via a base class pointer ? And what would happen if two derived classes would use different calling conventions ?
  • You can't assume that a calling convention is automatically inherited : the standard makes no guarantee, here
  • If you have to specify a calling convetion, prefer an external linkage specifier if possible (e.g. extern "C" ) because this is the only calling convention relevant semantic that is supported by the standard.

Additional information:

  • __cdecl, __stdcall, and other usual calling conventions
  • Calling convetions demistified


来源:https://stackoverflow.com/questions/28385849/conflicting-type-attributes-specified-for-virtual-destructor

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