2016-12-23 3 views
2

В file1.cc я пишуУ разных файлов разные области?

int i = 0; 

в file2.cc я пишу

#include <iostream> 

int i = 1; 

int main() 
{ 
    std::cout<< i << std::endl; 
    return 0; 
} 

В MacOS компилятор сообщает

duplicate symbol _i in: 
/var/folders/wn/q9648wb507j9l504vp2d_dwm0000gn/T/file1-bb8eca.o 
/var/folders/wn/q9648wb507j9l504vp2d_dwm0000gn/T/file2-b5e667.o 
ld: 1 duplicate symbol for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

Но не так, что разные файлы имеют их различные области, так что мы можем определить глобальную переменную в файле2 с тем же именем, что и в файле1? Кроме того, если различные файлы находятся в той же области, то почему это незаконно, чтобы превратить file2.cc как:

#include <iostream> 

int main() 
{ 
    std::cout<< i <<std::endl; 
    return 0; 
} 
+5

Если вы хотите, чтобы ваши глобальные переменные имели внутреннюю связь (то есть быть видимыми только в пределах файла, в котором они определены) - пометьте их как «статические» или поместите их в анонимное пространство имен. –

+0

вы должны иметь «extern i» в файле2.cc – Aram

+0

Глобальная переменная ** global ** - она ​​доступна везде. –

ответ

6

несколько определений одной глобальной переменной не допускается. Вы должны пометить свои переменные static, const или поместить их в анонимное пространство имен. Иначе они находятся в глобальном масштабе.

И ваш второй вопрос: код примера не компилируется, потому что компилятор не видит глобальную переменную из другого файла, потому что компилятор компилирует одну единицу перевода (файл C++) за раз. Вот почему вам нужно добавить extern i;. Это говорит компилятору, что переменная будет определена в другой единицы перевода.

После того, как все файлы были скомпилированы успешно, они будут связаны. Linker проверяет все единицы перевода. Когда вы получаете ошибку о нескольких определениях, эта ошибка возникает во время связывания.

+1

Неименованное правило пространства имен действует только из C++ 11, правильно? http://stackoverflow.com/questions/13396748/are-objects-in-anonymous-namespace-implicitly-static – gurka

+0

Спасибо! Ваш ответ отлично стирает мое замешательство :) – Felix

1

Глобальная область для файлов, связанных в одном и том же исполняемом файле, одинакова. Чтобы избежать этого, вы можете объявить его static, но это устарело в C++.
Правильный способ разделить область двух файлов - использовать namespaces.

1

Ваша переменная находится в том же объеме. Вы должны использовать пространства имен, чтобы объявлять переменные с тем же именем.

+0

Добавленный пример помогает лучше объяснить ответ – GurV

Смежные вопросы