c & c ++ связывание глобальных переменных по умолчанию, проблема множественного объявления и определения - PullRequest
27 голосов
/ 16 июня 2011

Например:

code1.c / .cpp

int a;

// ... and so on

code2.c / .cpp

int a;

int main(void) {
    return 0;
}

перейти к компиляции:

$gcc code1.c code2.c      # this is fine
$

$g++ code1.cpp code2.cpp  # this is dead
/tmp/ccLY66HQ.o:(.bss+0x0): multiple definition of `a'
/tmp/ccnIOmPC.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status

Существует ли какая-либо глобальная разница между переменными в C & C ++?

Ответы [ 4 ]

20 голосов
/ 16 июня 2011

Это не строго законно.int a; является предварительным определением в C. Вам разрешено несколько предварительных определений и самое большее одно не предварительное определение на единицу перевода каждого объекта с внешней связью в C, но только одно определение во всех единицах перевода в программе.

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

В C ++int a; - это всего лишь определение - здесь нет понятия предварительно - и по-прежнему незаконно иметь несколько определений объекта в единицах перевода программы.

Для случая C вы, возможно, захотите взглянуть на этот вопрос .

4 голосов
/ 16 июня 2011

Это недопустимо в обоих случаях, но компиляторы C обычно реализуют расширение.См. этот ответ .

2 голосов
/ 16 июня 2011

Существует три способа решения проблемы:

  1. Если переменная a одинакова в обоих файлах, вы должны объявить ее как extern во всех файлах, кроме одного.Ключевое слово extern сообщает компоновщику, что это имя находится в других файлах.

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

  3. Или вы можете использовать безымянное пространство имен.

1 голос
/ 16 июня 2011

компилятор g ++ более строг, чем компилятор gcc. Это также зависит от версии gcc, может быть более поздней версией gcc, т.е. 4.X и более, она может выдавать ту же ошибку.

Используйте extern, чтобы избежать

...