Объектные файлы с заголовками - PullRequest
0 голосов
/ 20 февраля 2012

Я немного запутался в объектных файлах, которые содержат заголовки.Я не понимаю, как охранники заголовков могут защитить вас, если они включены в несколько объектных файлов.

Например:

main.o <- main.cpp class.h
class.o <- class.cpp class.h
main.exe <- main.o class.o

Не содержит ли каждый объектный файл class.h, тем самымсделать для исполняемого файла две его копии?

Ответы [ 3 ]

3 голосов
/ 20 февраля 2012

Вы правы, и это не проблема. Защита заголовка не дает компилятору видеть две копии, но не влияет на компоновщик . На самом деле, компоновщик опирается на то, что существует две копии. В конце концов, это связывает эти два.

2 голосов
/ 20 февраля 2012

Объектные файлы не содержат заголовков;они содержат выходные данные компилятора.Но поднятый вами вопрос действителен: все, что в заголовке, может быть продублировано несколько раз в конечном коде.Грубо говоря, мы можем выделить две категории:

  1. Объявления, которые не создают ничего, что могло бы оказаться в выводе компилятора: такие как typedef или, в этом отношении, шаблоны и определения классов,Стандарт допускает дублирование определений при условии, что все они «идентичны».

  2. Объявления, которые вам запрещено копировать, и которые не должны быть в заголовке.Такие вещи, как переменные и функции.

На практике это немного сложнее, шаблон может быть создан для одного и того же типа в нескольких различных источниках, а экземпляр шаблона может бытьфункция.Или компилятор может не встроить встроенную функцию.Обычный способ справиться с этим - компилятор генерирует функцию в каждом модуле перевода, а компоновщик - выбрасывает дубликаты.(На самом деле, большинство компоновщиков не проверяют, действительно ли они дубликаты. Они просто выбрасывают все, кроме одного, выбираются более или менее случайным образом.)

0 голосов
/ 20 февраля 2012

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

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

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

В основном, заголовки содержат только прототипы функций (которые не генерируют код), определения классов (которые не генерируют код), определения встроенных функций или внешние ссылки. Последние 2 из них будут генерировать вещи в объектном файле, которые должны обрабатываться компоновщиком.

...