Рекомендуется всегда инициализировать объявления переменных на внешнем уровне в файлах, которые предназначены для помещения в библиотеку. Это повышают вероятность выявления случаев нежелательного совпадения имен внешних переменных в библиотечном файле и пользовательской программе. Если переменная в программе пользователя также инициализирована, то компоновщик обнаружит два инициализированных объявления одной и той же глобальной переменной и сообщит об ошибке.
Возможно наличие в одном исходном файле на внешнем уровне нескольких объявлений переменной с одним и тем же именем. Следующая таблица позволяет определить реакцию компилятора языка Си в различных ситуациях изменения спецификации класса памяти в объявлении. Слово "пусто" в таблице означает ситуацию отсутствия спецификации класса памяти. Очевидно, что компилятор СП MSC строже ограничивает возможность переопределения класса памяти переменной.
Класс 1 |
Класс 2 |
СП TC |
СП MSC |
extern |
static |
static |
static |
static |
пусто |
static |
ошибка |
static |
extern |
static |
static |
пусто |
static |
static |
ошибка |
Пример: /*
ИСХОДНЫЙ ФАЙЛ 1 */
/* объявление i,
ссылающееся на данное ниже определение i */
extern int i;
main()
{
i = i + 1;
printf("%d\n", i); /* значение i равно 4 */
next();
}
int i = 3; /* определение i */
next()
{
printf("%d\n", i); /* значение i равно 5 */
other());
}
/* ИСХОДНЫЙ ФАЙЛ 2 */
/* объявление i, ссылающееся на определение i в первом исходном файле */
extern int i;
other()
{
i = i + 1;
printf("%d\n", i); /*
значение i равно 6 */
}
Два исходных файла в совокупности содержат три внешних объявления i. Только в одном объявлении содержится инициализация:
int i = 3; — глобальная переменная i определена с начальным значением 3.
Самое первое объявление extern в первом исходном файле делает глобальную переменную i доступной прежде ее определения в файле. Без этого объявления функция main не могла бы использовать глобальную переменную i. Объявление переменной i во втором исходном файле делает глобальную переменную i доступной во втором исходном файле.
Все три функции выполняют одно и то же действие: увеличивают i
на 1 и печатают полученное значение. Значения распечатываются с помощью стандартной библиотечной функции printf. Печатаются значения 4, 5 и 6.
Если бы переменная i не была инициализирована ни в одном из объявлений, она была оы
неявно инициализирована нулевым значением при компоновке. В этом случае программа напечатала бы значения 1, 2 и 3.