внешнее объявление и определение в C - PullRequest
2 голосов
/ 12 апреля 2011

глобальная переменная может состоять из одного-двух разных классов хранения в C, насколько мне известно, и объявление может быть дано с двумя разными ключевыми словами, соответственно

extern int foo; //default
static int bar;

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

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

Мой компилятор (GCC) принимает

static int bar = 5;

, но подает жалобу на

extern int foo = 4;

Кажется, ожидается, чтоПеременные extern никогда не определяются с помощью ключевого слова extern.Это приводит к следующему вопросу :

Какой класс хранилища имеет объект 'foo' в приведенном выше примере в модуле, где он определен?

Ответы [ 4 ]

2 голосов
/ 12 апреля 2011

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

См. спецификатор класса внешнего хранения дляболее подробная информация.

0 голосов
/ 12 апреля 2011

На самом деле вы пропустили два класса хранения: авто и зарегистрироваться
Регистрация здесь не имеет значения, но класс хранения по умолчанию - auto.
Авто резервирует место для переменной где-то в памяти (что обычно требуется при объявлении переменной). Следует отметить, что для «авто переменных» новое пространство будет выделяться каждый раз, когда вводится область действия переменной. (то есть вызов функции func () из функции func (), когда func () объявляет переменную 'auto', приведет к двум различным переменным, и каждый вызов func () будет знать только о своей собственной переменной.
Из этого следует, что автоматические переменные, объявленные в глобальной области видимости, будут уникальными (поскольку область вводится только один раз).
Однако статические переменные всегда уникальны. Уникален в том смысле, что пространство будет выделяться только один раз. Это полезно, когда func () вызывает func (), и вы хотите, чтобы оба вызова функций работали с одной и той же переменной.
Внешние переменные - это просто ссылки на уникальные переменные.
Вы используете их, когда хотите получить доступ к глобальной переменной, объявленной в другом файле.
Учитывая файлы 1.c и 2.c, недостаточно объявить "int global;" в обоих файлах, поскольку пространство будет выделено дважды, а конфликт имен приведет к ошибке компоновки.
Следовательно, вы должны в одном файле зарезервировать пространство (используя «int global;»), а в другом файле указать компоновщику найти переменную с именем «global» в другом файле, написав «extern int global;».

0 голосов
/ 12 апреля 2011

Класс хранения по умолчанию: auto.

0 голосов
/ 12 апреля 2011

Внешняя переменная будет определена с глобальной областью действия (экспортированной) в той единице, где она определена:

int baz = 5;

...