Связь глобальных переменных c & c ++ по умолчанию, проблема с несколькими объявлениями и определениями
-
28-10-2019 - |
Вопрос
Например:
code1.c / .cpp
родовое словоcode2.c / .cpp
родовое словоперейти к компиляции:
родовое словоЕсть ли разница в связывании глобальных переменных между C и C ++?
Решение
Это не совсем закон.int a;
- это предварительное определение в C. Вам разрешено несколько предварительных определений и не более одного не предварительного определения на единицу перевода каждого объекта с внешней связью в C, но только одно определение для всех единиц перевода в программе.
Это широко используемое расширение, позволяющее использовать предварительные определения для нескольких единиц перевода на языке C, если не более одной единицы перевода содержат не предварительное определение, но это не является строго стандартным.
В C ++ int a;
- это просто определение - здесь нет понятия "предварительный" - и по-прежнему незаконно иметь несколько определений объекта в единицах перевода программы.
Для случая C вы можете посмотреть этот вопрос .
Другие советы
Это незаконно в обоих случаях, но компиляторы C обычно реализуют расширение.См. этот ответ .
Есть три пути решения проблемы:
-
Если переменная
a
одинакова в обоих файлах, вы должны объявить ее какextern
во всех файлах, кроме одного.Ключевое словоextern
сообщает компоновщику, что это имя находится в других файлах. -
Вы можете использовать ключевое слово
static
, чтобы ограничить область действия переменной одним файлом.В котором это заявлено. -
Или вы можете использовать безымянное пространство имен.
Компилятор g ++ более строгий, чем компилятор gcc. Это также зависит от версии gcc, может быть более поздняя версия gcc, т.е. 4.X и далее, она может выдавать ту же ошибку.
Чтобы избежать, используйте генерирующий код тегов