В разделе 7.1 стандарта C ++ упоминается extern как спецификатор класса хранения.

N3126 - «Спецификатор extern может применяться только к именам переменных и функций. Спецификатор extern не может использоваться в объявлении членов класса или параметров функции. Для связывания имени, объявленного со спецификатором extern, см. 3.5. [ Примечание. Ключевое слово extern также может использоваться в явных экземплярах и спецификациях связывания, но оно не является спецификатором класса хранилища в таких контекстах. - конец примечания]

Я понимаю это ключевое слово и его использование в контексте «спецификации связывания», но я не могу понять использование «extern» в качестве спецификатора хранилища.

  1. Разве все внешние имена не имеют статической продолжительности хранения?
  2. Если ответ на 1 - «да», то почему эта избыточность? C Совместимость?
3
Chubsdad 22 Окт 2010 в 08:46
И стандарт C99 добавляет typedef в набор спецификаторов класса хранения - typedef не имеет ничего общего с хранилищем или связью ...
 – 
Michael Burr
22 Окт 2010 в 10:36

3 ответа

Лучший ответ

extern - это спецификатор класса хранения . Это просто факт грамматики языка. extern оказывает ряд эффектов на семантику программы в зависимости от того, где она используется. Это не везде одинаково. Он влияет на продолжительность хранения и связь объектов, а также помогает определить, являются ли некоторые объявления также определениями или нет.

Например.:

int a; // Ex1

extern int b; // Ex2

Например, если Ex1 и Ex2 находятся в глобальной области видимости, то они оба будут ссылаться на объекты со статической продолжительностью хранения и внешней связью. Однако в C ++ первое будет определением (предварительное определение в C), а второе - нет. В этом примере extern не изменил продолжительность хранения или привязку объявленного объекта.

Если Ex1 и Ex2 встречаются в теле функции, то a будет ссылаться на объект с автоматической продолжительностью хранения и без связи, но b будет ссылаться на объект с внешней связью и статическая продолжительность хранения. В этом примере extern повлиял на значение объявления как в связи, так и в продолжительности хранения, а также в том, является ли это определением.

Наконец, в C ++ приведен пример, в котором единственным эффектом extern является изменение связи с внутренней на внешнюю.

const int c = 5; // static storage duration, internal linkage

extern const int d = 10; // static storage duration, external linkage
7
CB Bailey 22 Окт 2010 в 10:57

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

2
Ignacio Vazquez-Abrams 22 Окт 2010 в 08:57
Собственно, если посмотреть еще раз, например, 'изменчивый', я не понимаю, какое отношение это имеет к 'классу хранения'. Что именно означает / делает «класс хранения»?
 – 
Chubsdad
22 Окт 2010 в 09:05
1
Некоторые классы хранения (static, auto, register) определяют, в какой памяти будет храниться переменная. Другие классы хранения (const, volatile) влияют на то, как компилятор генерирует код для доступа к ним. extern тоже не умеет.
 – 
Ignacio Vazquez-Abrams
22 Окт 2010 в 09:07
Константные и изменчивые классы хранения? C ++ рассматривает их как спецификаторы типа, а не как спецификаторы класса хранения. Хотя не уверен насчет C.
 – 
Chubsdad
22 Окт 2010 в 09:27
@Chubsad: Нет, const и volatile не являются спецификаторами класса хранения, они являются квалификаторами типа. Поскольку вам разрешен только один спецификатор класса хранения в объявлении, если const где один, то (например) static const int x = 5; будет незаконным. Насколько мне известно, это верно как для C, так и для C ++.
 – 
CB Bailey
22 Окт 2010 в 10:43

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

0
Saurabh Raoot 31 Май 2018 в 18:17