GCC жалуется на двойное определение (где существует только одно)

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

Конкретная ошибка, которую я получаю, такова:

ld: duplicate symbol _fprintConfiguration in
/.../bits.build/Objects-normal/x86_64/Block.o and
/.../bits.build/Objects-normal/x86_64/bits.o

где Block.o содержит определение, а bits.o содержит драйвер.


Я уже провел некоторые исследования по этому вопросу, но кажется, что каждая проблема существует с людьми, которые фактически определяют это дважды в силу #include, но во всех моих файлах я использую только #import. Разве директива #import не должна «разумно» включать файлы? Есть ли другие причины, по которым я могу получить эту ошибку? Есть ли другие решения, которые я могу попробовать?

Спасибо за вашу помощь :)


person Sean Allred    schedule 14.06.2012    source источник


Ответы (1)


Проблема в том, что вы включаете одно и то же определение в несколько единиц перевода (как Block.o, так и bits.o). Чтобы это исправить, объявите функцию inline или переместите определение в (один) исходный (не заголовочный) файл.

Это ортогонально вопросу о #include против #import. Речь идет о многократном включении одного и того же кода в одну и ту же единицу перевода.

person Jesse Beder    schedule 14.06.2012
comment
Вау, я никогда не ожидал, что перенос определения из заголовочного файла в файл реализации изменит ситуацию. Насколько я понимаю, и #include, и #import по сути включают файлы в один массовый беспорядок единицы компиляции и компилируют его там. Почему удаление определения из файла заголовка имеет значение, если это так? - person Sean Allred; 14.06.2012
comment
Если только... Может быть, включение его в Block.m привело к конфликтам с фактической целью, включая его в bits.m, и вот тут компоновщик вырвало. Возможно, #import не так умен, как показано в документации;) - person Sean Allred; 14.06.2012
comment
@vermiculus, проблема в том, что когда определение находится в файле заголовка, для компоновщика оно выглядит так, как будто функция определена в двух разных единицах перевода (обе единицы включают один и тот же заголовок). - person Jesse Beder; 14.06.2012
comment
Да, это никогда не проблема, если что-то объявлено более одного раза, но определение этого более одного раза вызывает двусмысленность (даже если определения идентичны (область действия)). - person Sean Allred; 14.06.2012