6
_ZNSaIwEC1Ev
_ZNSaIwEC2Ev

这两个 C++ 符号不同,但被分解(使用 C++filt 或类似实用程序)成相同的形式:

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

为什么这样?会不会是 demangler 的缺陷或其他什么?

4

1 回答 1

7

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

在关于构造函数和析构函数的修改部分中,我们看到:

<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以调用适当的 scalar 结束operator delete。这对于绑定到虚拟析构函数是必要的,因为正确的operator delete可能是基类一无所知的静态类成员。
  • “完整的对象析构函数”包括D1与构造函数相反C1,包括对虚拟基类的析构函数的调用。
  • “基对象析构函数”包括与构造函数D2相反C2,省略了对虚拟基类析构函数的调用。

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

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

于 2018-04-13T21:12:38.680 回答