被破坏的C ++符号的模糊性

时间:2018-04-13 20:47:55

标签: c++ gcc demangler

_ZNSaIwEC1Ev
_ZNSaIwEC2Ev

这两个C ++符号有所不同,但是将它们(使用C ++过滤或类似实用程序)解压缩为相同的形式:

std::allocator<wchar_t>::allocator()
std::allocator<wchar_t>::allocator()

为什么这样?它可能是一个demangler的缺陷还是其他什么?

1 个答案:

答案 0 :(得分:5)

g ++使用Itanium ABI指定的名称修改方案(以及其他实现细节)。

mangling of constructors and destructors部分,我们看到:

<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
  • 包括C1的“完整对象构造函数”是初始化时直接使用的普通构造函数。
  • 派生类构造函数使用包含C2的“基础对象构造函数”来初始化其基类子对象。当涉及虚拟继承时,这可能与“完整”构造函数不同,因为只有完整的构造函数初始化虚拟基础,而基础构造函数则假设它们的虚拟基础已经初始化。
  • 包括C3在内的“完整对象分配构造函数”可能包含对operator new的调用。但据我所知,g ++实际上从未使用过这个。
  • 包含D0的“删除析构函数”通过调用相应的标量operator delete完成。这是绑定到虚拟析构函数所必需的,因为正确的operator delete可能是基类不知道的静态类成员。
  • 包括D1的“完整对象析构函数”与C1构造函数相反,包括对虚拟基类析构函数的调用。
  • 包含D2的“基础对象析构函数”与C2构造函数的反向类似,省略了对虚拟基类的析构函数的调用。

因此,您询问的错误名称的C1C2部分暗示了对C ++系统很重要且必须单独正确链接的信息。但是这些信息很难在伪代码声明中简要解释,所以demangling函数只是相同地描述了两个符号。

虽然std::allocator<T>通常没有任何虚拟基类,但这两个符号实际上可能指向相同的代码地址,但g ++只提供两个链接符号以保持一致性。