Неоднозначность деформированных символов C++

_ZNSaIwEC1Ev
_ZNSaIwEC2Ev

Эти два символа C++ различаются, но разбиты (с использованием C++ Filter или аналогичной утилиты) в одну и ту же форму:

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

Почему так? Может ли это быть дефект деманглера или что-то еще?

1 ответ

Решение

В 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 заканчивается звонком в соответствующий скаляр operator delete, Это необходимо привязать к виртуальному деструктору, потому что правильный operator delete может быть статическим членом класса, о котором базовый класс ничего не знает.
  • "Полный деструктор объекта", включая D1 это как обратная сторона C1 конструктор и включает вызовы деструкторов виртуальных базовых классов.
  • "Деструктор базового объекта", включая D2 это как обратная сторона C2 конструктор и пропускает вызовы деструкторов виртуальных базовых классов.

Итак C1 а также C2 части искаженных имен, о которых вы спрашивали, подразумевают информацию, которая важна для системы C++ и должна быть правильно привязана индивидуально. Но эту информацию сложно кратко объяснить в объявлении псевдокода, поэтому функция разборки просто описывает оба символа одинаково.

Хотя с тех пор std::allocator<T> обычно не имеет никаких виртуальных базовых классов, вполне вероятно, что два символа фактически указывают на один и тот же кодовый адрес, но g++ просто обеспечивает оба символа компоновщика для согласованности.

Другие вопросы по тегам