Ambiguity of de-mangled C++ symbols
Asked Answered
C

1

7
_ZNSaIwEC1Ev
_ZNSaIwEC2Ev

These two C++ symbols differ but are demangled (using C++filt or similar utility) into the same form:

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

Why so? Could it be a demangler's defect or what else?

Concuss answered 13/4, 2018 at 20:47 Comment(1)
Is it important for the inverse of the mangling function to be injective? I only see how it's important for the mangling function to be injective.Stroboscope
B
10

g++ uses the name mangling scheme (and other implementation details) specified by the Itanium ABI.

In the section on mangling of constructors and destructors, we see:

<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
  • The "complete object constructor" including C1 is the ordinary constructor directly used by initializations.
  • The "base object constructor" including C2 is used by a derived class constructor to initialize its base class subobject. This can be different from a "complete" constructor when virtual inheritance is involved, because only complete constructors initialize virtual bases, and base constructors instead assume their virtual bases have already been initialized.
  • The "complete object allocating constructor" including C3 presumably includes a call to operator new. But as far as I know, g++ never actually uses this one.
  • The "deleting destructor" including D0 finishes with a call to the appropriate scalar operator delete. This is necessary to tie to a virtual destructor because the correct operator delete might be a static class member which the base class knows nothing about.
  • The "complete object destructor" including D1 is like the reverse of the C1 constructor, and includes calls to destructors of virtual base classes.
  • The "base object destructor" including D2 is like the reverse of the C2 constructor, and omits calls to destructors of virtual base classes.

So the C1 and C2 pieces of the mangled names you asked about imply information which is important to the C++ system and must be correctly linked individually. But that information is difficult to briefly explain in a pseudo-code declaration, so the demangling function just describes both symbols identically.

Though since std::allocator<T> normally does not have any virtual base classes, it's likely that the two symbols actually point at the same code address, but g++ just provides both linker symbols for consistency.

Bastard answered 13/4, 2018 at 21:12 Comment(1)
In my case they do not point to the same address, but the code is identical.Concuss

© 2022 - 2024 — McMap. All rights reserved.