c++汇编输出中的重复析构函数
Duplicate Destructors in Assembler Output for C++
我目前正在尝试理解c++如何从一个小示例c++程序生成汇编。因此,我正在用各种优化测试以下程序:
#define noinline __attribute__ ((noinline))
class Test_Base {
public:
noinline Test_Base() {}
virtual noinline ~Test_Base() {}
void noinline method() { v_method(); }
private:
virtual void v_method()=0;
};
class Test1
: public Test_Base
{
public:
noinline Test1() {}
noinline ~Test1() {}
private:
void noinline v_method() {}
};
class Test2
: public Test_Base
{
public:
noinline Test2() {}
~Test2() {}
private:
void noinline v_method() {}
};
int main() {
volatile int x = 0;
Test_Base * b;
Test1 t1;
Test2 t2;
if( x )
b = &t1;
else
b = &t2;
b->method();
return 0;
}
但是查看这段代码(在ARMv7平台上使用-Os
编译),我发现构造函数和析构函数的所有定义都被包含了多次。下面是Test1符号表的相关部分:
00008730 w F .text 00000004 Test1::v_method()
000088d8 w O .rodata 00000014 vtable for Test1
000087d0 w F .text 00000020 Test1::Test1()
00008774 w F .text 0000001c Test1::~Test1()
00008710 w F .text 00000020 Test1::~Test1()
000088a4 w O .rodata 00000007 typeinfo name for Test1
00008898 w O .rodata 0000000c typeinfo for Test1
000087d0 w F .text 00000020 Test1::Test1()
00008710 w F .text 00000020 Test1::~Test1()
所以我有一个构造函数和两个析构函数(最后两个调用只是重复了相同的位置)。查看程序集,我观察到以下内容:
首先构造函数
000087d0 <Test1::Test1()>:
87d0: e92d4010 push {r4, lr}
87d4: e1a04000 mov r4, r0
87d8: ebfffff3 bl 87ac <Test_Base::Test_Base()>
87dc: e1a00004 mov r0, r4
87e0: e59f3004 ldr r3, [pc, #4] ; 87ec <Test1::Test1()+0x1c>
87e4: e5843000 str r3, [r4]
87e8: e8bd8010 pop {r4, pc}
87ec: 000088e0 .word 0x000088e0
我猜这是我让它做的。
现在析构函数0x8710:
00008710 <Test1::~Test1()>:
8710: e59f3014 ldr r3, [pc, #20] ; 872c <Test1::~Test1()+0x1c>
8714: e92d4010 push {r4, lr}
8718: e1a04000 mov r4, r0
871c: e5803000 str r3, [r0]
8720: ebfffff6 bl 8700 <Test_Base::~Test_Base()>
8724: e1a00004 mov r0, r4
8728: e8bd8010 pop {r4, pc}
872c: 000088e0 .word 0x000088e0
这里没有什么值得怀疑的。
现在析构函数0x8774:
00008774 <Test1::~Test1()>:
8774: e92d4010 push {r4, lr}
8778: e1a04000 mov r4, r0
877c: ebffffe3 bl 8710 <Test1::~Test1()>
8780: e1a00004 mov r0, r4
8784: ebffff69 bl 8530 <_init+0x44>
8788: e1a00004 mov r0, r4
878c: e8bd8010 pop {r4, pc}
我真的不知道这是做什么的,因为我不太熟悉ABI。我猜这与静态初始化有关。
这个附加析构函数的目的是什么?
如果我为x86_64编译相同的代码,我也会得到重复的析构函数,所以这似乎不是特定于系统的
第一个是非虚析构函数,用于在编译时知道动态类型时销毁自动对象或静态对象。
第二个是用于多态删除的虚拟"thunk"。它调用非虚拟析构函数来销毁对象,然后调用operator delete
来释放内存。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- C++ 防止在映射中放置()时调用析构函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 调用析构函数以释放动态分配的内存
- c++汇编输出中的重复析构函数