Включить охранников не работает? (500 ошибок типа LNK2005 x уже определены в y.obj)

У меня большой проект (400 файлов), и во всех заголовках есть защита и все, но я получаю 500 ошибок LNK2005.

Может ли быть так, что у меня есть тела функций, определенные в некоторых заголовках? Потому что я видел то же самое в заголовках утилит DirectX (некоторые функции в DirectXCollision полностью указаны в заголовке).

Или это может быть потому, что они используют файлы .inl вместо .cpp?

1

Решение

Может ли быть так, что у меня есть тела функций, определенные в некоторых заголовках?

Да, это может быть. Определение функции в нескольких единицах перевода приводит к ошибке определения дублированного символа.

Вы можете обойти ошибку дублирования, объявив эти функции inline, [7.1.2] / 2 гласит:

Объявление функции (8.3.5, 9.3, 11.3) со встроенным спецификатором объявляет встроенная функция. Встроенный спецификатор указывает реализации, что внутренняя замена тела функции в точке вызова должна быть предпочтительнее обычного механизма вызова функции. Реализация не требуется для выполнения этой внутренней замены в точке вызова; тем не менее, даже если эта встроенная замена не указана, другие правила для встроенных функций, определенные в 7.1.2, все равно должны соблюдаться.

3

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

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

Вы можете обойти это, объявив вашу функцию встроенной, тогда компилятор скопирует / вставит их.

1

Вы определяете глобальные переменные в ваших заголовочных файлах? Это может быть причиной ошибки.
И включить охрану не поможет.

Глобальная переменная должна быть определена только в одной единице перевода и должна быть расширена во всех других единицах перевода.

Например,
в х.ч у вас есть

int myVar;

Теперь вы #include x.h в обоих a.cpp & b.cpp,
тогда вы получите ошибку компоновщика, даже если вы включили охрану в x.h

Потому что теперь myVar будет определен как в a.obj, так и в b.obj, а компоновщик найдет 2 myVars.

0
По вопросам рекламы [email protected]