Что такое «группа деструкторов»? символ в gcc имя искажается

https://stackoverflow.com/a/6614369/1091587 имеет краткое изложение типов деструкторов (D0, D1, D2), которые появляются, когда вы читаете таблицу символов программы, скомпилированной с использованием искажения имен типа «gcc3». Существуют также соответствующие конструкторы C0 / C1 / C2. С g ++ — 4.7 (возможно, раньше) появляется новая пара ctor / dtor, а именно C5 / D5, но только как символ отладки.

$ cat i.cpp
class X { public: virtual ~X() {}; };
int main(void) { X x; return 0; };
$ g++ -c i.cpp
$ nm i.o | grep 5
0000000000000000 n _ZN1XC5Ev
0000000000000000 n _ZN1XD5Ev
$ c++filt -n _ZN1XC5Ev _ZN1XD5Ev
X::X()
X::~X()

Источник demangler называет объект D5 «gnu_v3_object_dtor_group», но что такое группа dtor и для чего она нужна? clang ++ — 3.3 его не излучает, а http://gcc.gnu.org/ml/gcc-patches/2011-11/msg00383.html предполагает, что это может быть связано с новой функцией транзакционной памяти в gcc.

3

Решение

Этот патч LLVM а также эта ошибка GCC предоставить больше фона. Перейдя по ссылкам, которые я нашел Ошибка 3187 — GCC устанавливает две копии конструкторов который кажется источником всего этого:

Две (иногда три) идентичные копии конструкторов и деструкторов
установлены Компоновщик не подведет, но исполняемые файлы
на 20% больше (на нашем реальном примере), чем необходимо.

Вы можете найти много дискуссий о gcc-patches ML, если вы ищете «PR c ++ / 3187» (например). По сути, C5 / D5 сам по себе не конструктор / деструктор, а КОМДАТ группа содержащий два или более «основных» конструкторов / деструкторов. Это гарантирует, что все функции в группе либо используются в конечном двоичном файле, либо все отбрасываются (для обеспечения соблюдения «правила одного определения»).

Результатом обсуждений в вышеупомянутых ошибках, кажется, являются:

Для любого класса реализация имеет возможность использовать один comdat для
конструктор / деструктор или использование C5 / D5 comdat. Я могу сделать это
решение, основанное на любом критерии прибыльности. Если вы используете комод C5 / D5
правила

  • Comdat C5 должен иметь C1 и C2.
  • Если у класса есть виртуальный деструктор, то у D5 comdat должны быть D0, D1 и D2
  • Если в классе есть не виртуальный деструктор, в комитате D5 должны быть только деструкторы D1 и D2. Это правда, даже если
    реализация использует D0 вместо вызова D1 + _ZdlPv для реализации
    «удалить * х»

Вы можете увидеть комдаты, например, сбросить файл с readelf -G:

COMDAT group section [    1] `.group' [_ZN1XD5Ev] contains 2 sections:
[Index]    Name
[   10]   .text._ZN1XD2Ev
[   12]   .text._ZN1XD0Ev

COMDAT group section [    2] `.group' [_ZN1XC5Ev] contains 1 sections:
[Index]    Name
[   14]   .text._ZN1XC2Ev

(Это с GCC 4.6, вероятно, поэтому он не соответствует определению выше)

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector