Почему у LLVM-битового кода есть повторяющиеся символы для конструкторов? [Дубликат]

В соответствии с сообщением об ошибке («Не удалось найти или загрузить основной класс») существуют две категории проблем:

  1. Основной класс не найден
  2. Основной класс не может быть загружен (этот случай не полностью обсуждается в принятом ответе).

Основной класс не может быть найден, если в имени полного класса или его неправильном синтаксисе указан или он не существует в предоставленном пути к классам.

Основной класс не может быть загружен, когда класс не может быть запущен, обычно основной класс расширяет другой класс и этот класс не существует в предоставленном пути к классам.

Например:

public class YourMain extends org.apache.camel.spring.Main

Если верблюжья пружина не включена, эта ошибка будет сообщена.

83
задан osgx 18 July 2013 в 17:12
поделиться

1 ответ

Начнем с того, что GCC следует Itanium C ++ 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 & amp; A подразумевает, что это просто a -product поддержки полиморфизма, хотя в этом случае это не требуется.
  • Обратите внимание, что c++filt используется для включения этой информации в ее демонтированный вывод, , но больше не работает .
  • Этот вопрос на форуме задает один и тот же вопрос, и единственный ответ не помогает лучше ответить на него, за исключением того, что GCC может избежать испускания двух конструкторов, когда полиморфизм не задействован и что это поведение должно быть улучшено в будущем.
  • Эта публикация в группе новостей описывает проблему с установкой точек останова в конструкторах из-за этого двойного испускания. Еще раз заявлено, что корень проблемы - это поддержка полиморфизма.

Фактически это указано как «известная проблема» GCC :

G ++ испускает две копии конструкторов и деструкторов.

В общем случае существуют три типа конструкторов (и деструкторов).

  • Полный конструктор объекта / destructor.
  • Конструктор / деструктор базового объекта.
  • Выделение конструктора / дезактивация деструктора.

Первые два отличаются друг от друга, когда виртуальная база классы


Значение этих разных конструкторов выглядит следующим образом :

  • «Полный объект-конструктор ". Он дополнительно создает виртуальные базовые классы.
  • «Конструктор базового объекта». Он создает сам объект, а также элементы данных и не виртуальные базовые классы.
  • «Назначение конструктора объектов». Он делает все, что делает полный конструктор объектов, а также вызывает новый оператор для фактического выделения памяти ... , но, видимо, это обычно не видно.

Если у вас нет виртуальных базовых классов, [первые два] идентичны; GCC будет на достаточных уровнях оптимизации фактически называть символы для одного и того же кода для обоих.

115
ответ дан Community 31 August 2018 в 19:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: