Почему делает extern int n
не компилируют, когда n объявляется (в другом файле) static int n
, но работы при объявлении int n
? (Оба из этих объявлений были в объеме файла.)
В основном, почему int n
в файле определяют объем не того же как static int n
в том же объеме? Это только относительно экстерна? Если так, что относительно экстерна я - пропавшие без вести?
Вся цель static
состоит в том, чтобы объявить, что переменная является частной для исходного файла, который объявлен в . Таким образом, он выполняет свою работу по предотвращению подключения извне.
Имейте в виду, что существует четыре варианта определения переменной области видимости файла:
int blah = 0;
- blah определено в этом файле и доступно из других файлов. Определения в других файлах дублируются и приводят к ошибкам. extern int blah;
- blah должен быть определен в другом месте и на него следует ссылаться из этого файла. int blah;
- это моральный эквивалент FORTRAN COMMON
.Вы можете иметь любое количество из них в файлах, и все они разрешаются компоновщиком в один общий int
. (*) static int blah;
(необязательно с инициализатором) - это статично. Это полностью закрыто для этого файла. Он не виден externs в других файлах, и у вас может быть много разных файлов, каждый из которых объявляет static TYPE blah;
, и все они разные . Для пуристов в аудитории: 'file' = единица компиляции .
Обратите внимание, что статические внутренние функции (не в области видимости файла) имеют еще более узкую область видимости: если две функции объявляют static int bleh = 0;
даже в одном файле, они не связаны.
(*): для тех из вас, кто не знаком: в обычном шаблоне одна единица компиляции должна определять глобальную переменную, а другие могут ссылаться на нее. Он «живет» в этом блоке компиляции. В случае (3), приведенном выше, ни один файл (или все файлы) не определяет его. Если в двух файлах указано int blah = 0;
, компоновщик будет жаловаться на несколько определений. Если в двух файлах написано int blah;
, компоновщик весело создает один глобальный int
и заставляет весь код ссылаться на него.
В стандартном C есть две области действия для переменных, объявленных вне функции. Статическая переменная видна только внутри модуля компиляции (т. Е. Файла), который ее объявил, а нестатические переменные видны во всей программе.Объявление
extern
говорит, что расположение переменной еще не известно, но будет отсортировано компоновщиком; он совместим с нестатическими переменными, но extern static
- просто сумасшедший треп!
Конечно, в наши дни на практике есть и другие возможности. В частности, теперь существуют уровни области видимости между отдельным исходным файлом и целой программой; уровень единой разделяемой библиотеки полезен (настраивается с помощью таких механизмов, как атрибуты функций GCC). Но это всего лишь вариация на тему нестатических переменных; static
сохраняет ту же интерпретацию, что и раньше.