Связывание C с методами, определенными в определении класса

#c #class #methods #linker

#c #класс #методы #компоновщик

Вопрос:

Ради любопытства, если вы помещаете определение метода внутри определения класса в заголовке, а компилятор не вставляет его, то в какой объектный файл или файлы этот метод помещается для доступа на этапе компоновки? Помещается ли это в каждый obj-файл, который включает заголовок, а затем дополнительные копии выбрасываются на этапе компоновки?

Комментарии:

1. Вы всегда можете попробовать такие утилиты, как «objdump» и «nm», чтобы знать это. 🙂

2. Определения функций-членов внутри определения класса являются встроенными по определению (в частности, 9.3 / 2 Стандарта), точно так же, как если бы они были объявлены inline .

Ответ №1:

Помещается ли это в каждый obj-файл, который включает заголовок, а затем дополнительные копии выбрасываются на этапе компоновки?

В общем, да. Смотрите этот документ.

Ответ №2:

Это зависит от компилятора, но GCC, по крайней мере, попытается поместить его в тот же объектный файл, что и первый нестроевой элемент. Если все элементы являются встроенными, то в каждом объектном файле, для которого требуется функция, будет копия (не обязательно все файлы, которые включают определение класса), а дополнительные копии выбрасываются при связывании.

Ответ №3:

Если компилятор отклоняет встраивание некоторой функции-члена, которая определена в строке в теле класса или определяется как inline функция вне тела класса, компилятор вставит скомпилированную версию функции в каждый obj-файл, который использует эту функцию. Обратите внимание, что это отличается от вставки скомпилированной версии каждой функции, объявленной в заголовке. Рассматриваемый файл должен вызывать эту (предположительно) встроенную функцию.

И да, компоновщик удалит дублирующиеся записи. Символы, сгенерированные в таблице символов для этих встроенных функций, имеют слабую связь. Сравните с функциями, которые не встроены: они имеют обычную связь, и если одна из них реплицируется, у вас неопределенное поведение. Типичный ответ компоновщика — пожаловаться, а затем умереть.