глобальная переменная В.С. файловая переменная в C ++ - PullRequest
8 голосов
/ 11 февраля 2009

В чем разница между глобальной переменной и файловой переменной в C ++?

Спасибо!

Ответы [ 4 ]

14 голосов
/ 11 февраля 2009

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

Статический глобальный метод устарел в C ++ в пользу анонимных пространств имен. Любые объявления, помещенные в анонимное пространство имен, также доступны только из этого файла.

7 голосов
/ 11 февраля 2009

C ++ программы компилируются по одной единице перевода за раз (в основном это означает, что каждый файл .cpp компилируется независимо).

По умолчанию переменные, которые не являются const, функции, которые не inline и typedef s, имеют внутреннюю связь : это означает, что они не видны другим единицам перевода. Если другие единицы перевода ссылаются на символ, имеющий внутреннюю связь (после объявления его , для которого требуется ключевое слово extern для переменных), компоновщик не сможет их найти.

Чтобы явно указать внутреннюю связь, используйте ключевое слово static или, что лучше, используйте безымянные пространства имен.

4 голосов
/ 11 февраля 2009

Примечание: Эти правила применяются к 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))

0 голосов
/ 11 февраля 2009

Разница лишь в том, что файловые переменные доступны только внутри файла. Но у них одинаковое время жизни.

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