Ответ 1
Начнем с объявления, что GCC следует Itanium С++ ABI.
В соответствии с ABI, искаженное имя для вашего Thing::foo()
легко анализируется:
_Z | N | 5Thing | 3foo | E | v
prefix | nested | `Thing` | `foo`| end nested | parameters: `void`
Вы также можете прочитать имена конструкторов, как показано ниже. Обратите внимание, что конструктор "name" не указан, но вместо этого: C
:
_Z | N | 5Thing | C1 | E | i
prefix | nested | `Thing` | Constructor | end nested | parameters: `int`
Но что это за C1
? Ваш дубликат имеет C2
. Что это значит?
<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
Подождите, почему это так просто? Этот класс не имеет базы. Почему у него есть "конструктор объектов" и "конструктор базового объекта" для каждого?
-
Этот Q & A подразумевает, что это просто побочный продукт поддержки полиморфизма, хотя в этом случае он фактически не требуется.
-
Обратите внимание, что
c++filt
используется для включения этой информации в ее демонтированный вывод, но больше не существует. -
Этот пост форума задает один и тот же вопрос, и единственный ответ не помогает лучше ответить на него, кроме что GCC может избегать испускания двух конструкторов, когда полиморфизм не задействован, и что это поведение должно быть улучшено в будущем.
-
Эта публикация в группе новостей описывает проблему с установкой точек останова в конструкторах из-за этого двойного излучения. Он снова заявил, что корень проблемы - поддержка полиморфизма.
Фактически это указано как "известная проблема" GCC:
g++ испускает две копии конструкторов и деструкторов.
В общем случае существуют три типа конструкторов (и деструкторы).
- Полный конструктор/деструктор объекта.
- Конструктор/деструктор базового объекта.
- Назначающий конструктор/деаллоцирующий деструктор.
Первые два отличаются друг от друга, когда виртуальные базовые классы участие.
Значение этих разных конструкторов выглядит следующим образом:
-
"Полный конструктор объектов". Он дополнительно создает виртуальные базовые классы.
-
"Конструктор базового объекта". Он создает сам объект, а также элементы данных и не виртуальные базовые классы.
-
"Назначение конструктора объектов". Он делает все, что делает полный конструктор объектов, а также вызывает новый оператор для фактического выделения памяти... но, видимо, это обычно не видно.
Если у вас нет виртуальных базовых классов, [первые два] являются тождественны; GCC будет, на достаточных уровнях оптимизации, фактически псевдонимом символы для одного и того же кода для обоих.