2009-08-25 4 views
14

Я начинаю сомневаться в полезности ключевого слова «extern», которое используется для доступа к переменным/функциям в других модулях (в других файлах). Разве мы не делаем то же самое, когда мы используем препроцессор #include для импорта файла заголовка с помощью прототипов переменных/функций или определений функций/переменных?В чем разница между использованием файлов extern и #include?

ответ

17

extern необходим, поскольку он заявляет, что символ существует и имеет определенный тип и не выделяет для него хранилище.

Если вы:

int foo; 

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

Вместо этого, если у вас есть:

extern int foo; 

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

один (и только один) исходный файл будет содержать

int foo; 

, который создает один экземпляр Foo для линкера, чтобы решить.

+2

Но разве вы не можете получить доступ к int foo без объявления с помощью extern int foo, пока вы включаете заголовочный файл, содержащий его определение? –

+2

Как упоминалось в jcopenha, #include просто вставляет текст из включенного файла в исходный файл - компилятор действительно не знает о включенных файлах и не относится к ним специально. Итак, если у вас есть A.c, B.c и C.c, каждый с «int foo», и вы связываете их вместе, как вы разрешаете foo? Он существует в трех разных местах. extern просто означает, что символ существует где-то в другом месте. Вы можете использовать его, но кто-то другой несет ответственность за его создание. – Michael

+0

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

2

№ #include - это команда препроцессора, в которой говорится: «Поместите весь текст из этого другого файла прямо здесь». Таким образом, все функции и переменные во включенном файле определяются в текущем файле.

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