什么是 gcc 名称重整中的"destructor group"符号
What is a "destructor group" symbol in gcc name mangling
https://stackoverflow.com/a/6614369/1091587 简要介绍了当您读取使用 "gcc3" 类型名称重整编译的程序的符号表时出现的析构函数类型(D0、D1、D2)。还有相应的构造函数 C0/C1/C2。在 g++-4.7(可能更早)中,出现了一个新的 ctor/dtor 对,即 C5/D5,但仅作为调试符号。
$ cat i.cpp
class X { public: virtual ~X() {}; };
int main(void) { X x; return 0; };
$ g++ -c i.cpp
$ nm i.o | grep 5
0000000000000000 n _ZN1XC5Ev
0000000000000000 n _ZN1XD5Ev
$ c++filt -n _ZN1XC5Ev _ZN1XD5Ev
X::X()
X::~X()
demangler 源称 D5 对象为"gnu_v3_object_dtor_group",但究竟什么是 dtor 组,它有什么用? clang++-3.3 不会发出它,http://gcc.gnu.org/ml/gcc-patches/2011-11/msg00383.html 表明它可能与 gcc 中的新事务内存功能有关。
这个LLVM补丁和这个GCC错误提供了更多的背景信息。通过点击链接,我发现了错误 3187 - gcc 放下了两个构造函数的副本,这似乎是这一切的起源:
构造函数和析构函数的两个(有时三个)相同副本 被放下。链接器不会失败,但生成的二进制文件 比必要的大 20%(在我们的真实示例上)。
如果你搜索"PR c c ++/3187"(例如),你可以找到许多关于gcc补丁ML的讨论。基本上,C5/D5 本身不是一个构造函数/析构函数,而是一个包含两个或多个"基本"构造函数/析构函数的 COMDAT 组。这可确保组中的函数要么全部用于最终二进制文件,要么全部丢弃(以强制执行"一个定义规则")。
上述错误中讨论的结果似乎是:
对于任何类,实现都可以选择使用每个 comdat 构造函数/析构函数或使用 C5/D5 组合。我可能会这样做 基于任何盈利标准的决策。如果使用 C5/D5 通信 规则是
- C5 通信必须具有 C1 和 C2。
- 如果类具有虚拟析构函数,则 D5 组合必须具有 D0、D1 和 D2
- 如果类具有非虚拟析构函数,则 D5 组合必须只有 D1 和 D2 析构函数。即使 实现使用 D0 而不是对 D1 + _ZdlPv 的调用来实现 "删除 *x"
您可以通过例如转储带有readelf -G
的文件来查看 comdats:
COMDAT group section [ 1] `.group' [_ZN1XD5Ev] contains 2 sections:
[Index] Name
[ 10] .text._ZN1XD2Ev
[ 12] .text._ZN1XD0Ev
COMDAT group section [ 2] `.group' [_ZN1XC5Ev] contains 1 sections:
[Index] Name
[ 14] .text._ZN1XC2Ev
(这是GCC 4.6,这可能就是它与上述定义不匹配的原因)
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 合法的方式将destructor信息存储到void*
- 检查destructor是否正在破坏所有动态内存
- 无法删除在destructor中的成员指针的课程
- 简单链接列表程序中的Destructor segfault
- IS类型INFO自动更新了以前调用Destructor
- 如何解决"expected constructor, destructor, or type conversion before ‘(’ token"错误?
- 快速'group by/count' std::vector<std::u16string> 变成 std::map<u16string, int>
- {app.exe!_com_error::'vector delete destructor'(unsigned int)}
- 我应该重置Destructor中的原始成员变量
- 从Q开始关闭QDialog时,请致电Destructor
- 为什么构造函数的数量与Destructor调用的数量不匹配
- 用const_iterator成员调用类destructor时堆积损坏
- 当我要退出应用程序时,如何在QT中自动调用destructor
- 在MSVC上的数组初始化期间,destructor在不复制或移动构造方的情况下调用
- 为什么不在C++中调用Destructor
- "Destructor already defined"专用析构函数
- 规则"A user-defined but do-nothing destructor is also a non-trivial destructor"太严格了?
- 明确调用`int` destructor-为什么需要类型的别名
- 什么是 gcc 名称重整中的"destructor group"符号