为什么有两个虚拟析构函数?

逆向工程 C++ 安卓 手臂 虚函数
2021-06-16 10:39:10

IDA 反汇编的虚函数表(VFT,也称为虚方法表,VMT)的开头是这样的:

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

并将其c++filt解码为

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

在这里我们看到_ZN13QSystemLocaleD2Ev_ZN13QSystemLocaleD0Ev,都由c++filtto转换QSystemLocale::~QSystemLocale()

(+1 是正常的,该位在 ARM 上选择正确的指令集)。

Qt 源代码声明:

virtual ~QSystemLocale();

为什么有两个虚拟析构函数?

(我使用 ARM、Android NDK(gcc/g++)、C++、Qt)。

1个回答

根据文档,第一个是基对象析构函数,第二个是删除析构函数。

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

根据ARM IHI 0041D文档,这些析构函数之间的区别如下:

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.