The beginning of the virtual function table (VFT, also virtual method table, VMT) disasembled by IDA goes as:

 _ZTV13QSystemLocale DCD 0, _ZTI13QSystemLocale, _ZN13QSystemLocaleD2Ev+1, _ZN13QSystemLocaleD0Ev+1

and c++filt decodes it as

 vtable for QSystemLocale DCD 0, typeinfo for QSystemLocale, QSystemLocale::~QSystemLocale()+1, QSystemLocale::~QSystemLocale()+1

Here we see _ZN13QSystemLocaleD2Ev and _ZN13QSystemLocaleD0Ev, both transformed by c++filt to QSystemLocale::~QSystemLocale().

(+1 is normal, the bit selects the right instruction set on ARM).

The Qt source declares:

virtual ~QSystemLocale();

Why there are two virtual destructors?

(I work with ARM, Android NDK (gcc/g++), C++, Qt).

1 Answer 1


According to documentation the first one is base object destructor and the second one is deleting destructor.

Constructors and destructors are simply special cases of <unqualified-name>, where the final <unqualified-name> of a nested name is replaced by one of the following:

  <ctor-dtor-name> ::= C1   # complete object constructor
           ::= C2   # base object constructor
           ::= C3   # complete object allocating constructor
           ::= D0   # deleting destructor
           ::= D1   # complete object destructor
           ::= D2   # base object destructor

According to ARM IHI 0041D document the difference between these destructors is as follows:

This ABI requires C1 and C2 constructors to return this (instead of being void functions) so that a C3 constructor
can tail call the C1 constructor and the C1 constructor can tail call C2.
Similarly, we require D2 and D1 to return this so that D0 need not save and restore this and D1 can tail call D2 (if
there are no virtual bases). D0 is still a void function.
  • Is Itanium ABI relevant to ARM? May 13, 2014 at 9:00
  • I've seen the same things in ARM abi documents. The difference between these destructors is restoring and preserving "this" pointer. I'll update the answer.
    – w s
    May 13, 2014 at 9:06
  • @18446744073709551615: yes. It's relevant to many C++ implementations, regardless of platform.
    – Igor Skochinsky
    May 13, 2014 at 11:11
  • @ws: in fact, the difference is that the deleting destructor must deallocate the memory occupied by the object, in addition to destructing the members. I.e. it's used to implement the delete pObj; statements. The return value convention is mandated by ARM to reduce code duplication but it's not a requirement of the the base C++ ABI.
    – Igor Skochinsky
    May 13, 2014 at 11:15
  • Also stackoverflow.com/a/6921467 May 14, 2014 at 2:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.