Примечание: Эти правила применяются к C ++ так же, как и к C, с некоторыми действиями по определению пространства классов / структуры / имен. (Я не заметил, что вопрос был о C ++, а не о C.)
Помните, что (в большинстве случаев) исходные файлы C компилируются в объектные файлы. Объектные файлы имеют таблицу экспорта, которая сообщает компоновщику (при компоновке), какие символы он предоставляет. Символ - это имя (его точное имя зависит от ABI), относящееся к функции или переменной (в большинстве случаев).
Когда вы объявляете глобальную переменную в вашем исходном файле C, например:
// fileA.c
int hello = 42;
void printMessage() {
printf("Hello, %d world(s)!\n", hello);
}
hello
и printMessage
экспортируются. Когда объектный файл C запрашивает символ с именем 'hello
' (при условии простого ABI), компоновщик связывает его с hello
, экспортированным с помощью fileA.c
.
Теперь по другому делу. Когда вы объявляете локальную переменную файла следующим образом:
// fileB.c
static int world = 9001;
static void messagePrint() {
printf("It's over %d!\n", world);
}
world
и messagePrint
экспортируются , а не . Когда объектный файл C запрашивает символ с именем 'hello
', компоновщик не может связать его с hello
из fileB.c
, поскольку в fileB.obj
(или где-либо еще) нет информации об этом.
Как messagePrint
может знать о world
? Оба находятся в одном блоке перевода. Сфера берет здесь. Я уверен, что вы найдете много информации о области через Google .
(Соответствует ли имя символа стандарту имени функции / переменной в C? Я знаю, что оно отличается для C ++ (где нет стандартизации для искажения имени), поэтому я в первую очередь упоминаю ABI.)
((Если ABI правильный термин, даже?; P))