Почему внешняя ссылка не связана со статической переменной? - программирование
Подтвердить что ты не робот

Почему внешняя ссылка не связана со статической переменной?

Почему extern int n не компилируется при объявлении n (в другом файле) static int n, но работает, когда объявляется int n? (Оба эти объявления были в области файлов.)

В принципе, почему int n в области файлов не совпадает с static int n в той же области? Это только по отношению к внешнему виду? Если да, то как насчет extern я не хватает?

4b9b3361

Ответ 1

Целая цель static состоит в том, чтобы объявить, что переменная закрыта для исходного файла, который объявлен в. Таким образом, он делает именно свою работу по предотвращению соединения с внешним.

Имейте в виду, что существует четыре варианта определения переменной области видимости файла:

  • int blah = 0; - blah определен в этом файле и доступен из других файлов. Определения в других файлах являются дубликатами и приводят к ошибкам.
  • extern int blah; - blah должен быть определен в другом месте и ссылается на этот файл.
  • int blah; - Это моральный эквивалент FORTRAN COMMON. Вы можете иметь любое количество из них в файлах, и все они разрешены компоновщиком для одного общего int. (*)
  • static int blah; (необязательно с инициализатором) - это статично. Он полностью закрыт для этого файла. Он не виден внешним файлам в других файлах, и у вас может быть много разных файлов, которые объявляют static TYPE blah;, и все они разные.

Для пуристов в аудитории: 'файл' = единица компиляции.

Обратите внимание, что статические внутренние функции (не в области файлов) еще более жестко ограничены: если две функции объявляют static int bleh = 0; даже в одном файле, они не связаны.

(*): для тех из вас, кто не знаком: в обычном шаблоне один блок компиляции должен определить глобальную переменную, а другие могут ссылаться на нее. Он "живет" в этой единице компиляции. В случае (3), выше, ни один файл (или все файлы) не определяет его. Если два файла говорят int blah = 0;, компоновщик будет жаловаться на несколько определений. Если два файла говорят int blah;, компоновщик весело создает единый глобальный int и заставляет весь код ссылаться на него.

Ответ 2

В стандарте C существуют две области для переменных, объявленных вне функции. Переменная static видна только внутри единицы компиляции (то есть файла), которая объявила его, а нестатические переменные видны во всей программе. Объявление extern говорит, что местоположение переменной еще неизвестно, но будет сортироваться компоновщиком; он совместим с нестатическими переменными, но extern static - просто сумасшедший разговор!

Конечно, на практике в наши дни есть и другие возможности. В частности, в настоящее время существуют уровни охвата между одним исходным файлом и целой программой; уровень одной общей библиотеки является полезной (настраивается с помощью таких механизмов, как атрибуты функции GCC). Но это всего лишь вариация темы нестатических переменных; static сохраняет ту же интерпретацию, что и раньше.

Ответ 3

iv.c: 2: 1: ошибка: несколько классов хранения в спецификаторах объявлений  extern static int i;  ^

Это то, что мы получаем от попытки статической переменной. Объявление extern static int i; - аналогично объявлению float int i; Вы не можете иметь float и int в одной и той же декларации? Аналогично, вы не можете иметь extern и static в той же декларации.

Ответ 4

Согласно документации MSDN:

При изменении переменной ключевое слово static указывает, что переменная имеет статическую продолжительность (она выделяется при запуске программы и освобождается при завершении программы) и инициализирует ее до 0, если не указано другое значение. При изменении переменной или функции в области файла ключевое слово static указывает, что переменная или функция имеет внутреннюю привязку (ее имя не видно извне файла, в котором она объявлена).

http://msdn.microsoft.com/en-us/library/s1sb61xd(v=vs.80).aspx: июнь 2013 г.