Почему предоставление явного инициализатора для extern внутри функции не отменяет extern? - PullRequest
6 голосов
/ 07 мая 2020

Согласно C ++ Primer , мы можем предоставить инициализатор для переменной, определенной как extern, но это отменяет extern. Определение extern с инициализатором:

extern double pi = 3.1416; // definition

В книге также говорится, что предоставление инициализатора для extern внутри функции является ошибкой. Эти два утверждения вместе, на мой взгляд, немного сбивают с толку, и они вызывают у меня следующие вопросы: extern внутри функции нет?

Я также не понимаю, почему кому-то может понадобиться получить объявление, добавляющее ключевое слово extern, и предоставить инициализатор. Разве это не то же самое, что определение переменной и предоставление ей инициализатора? Если нет, то почему? Является ли ответ причиной того, почему мы не можем предоставить инициализатор для внешнего вида внутри функции?

1 Ответ

3 голосов
/ 07 мая 2020

Согласно C ++ Primer, мы можем предоставить инициализатор для переменной, определенной как extern, но это отменяет extern.

Только частично.

Предоставление инициализатора заставляет объявление быть определением (за исключением случая некоторых stati c членов классов). Таким образом, он частично противодействует эффекту extern, который обычно подавляет определение. Однако extern может иметь другие эффекты, и инициализатор не обнуляет их.

В книге также сказано, что предоставление инициализатора для внешнего вида внутри функции является ошибкой.

Да. В области действия блока extern используется для принудительной привязки объявления к внешней или внутренней связи (вместо объявления локальной переменной). Однако язык запрещает определять такую ​​переменную в локальной области видимости. Вы можете только объявить его там и предоставить соответствующее определение в области пространства имен. Если вы предоставляете инициализатор, тогда вы пытаетесь определить переменную там, что недопустимо.

Если предоставление инициализатора на внешнем интерфейсе вне любой функции может переопределить внешний вид, зачем его предоставлять? на внешнем внутри функции, а не?

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

Я также не понимаю, почему кому-то может понадобиться и то, и другое. получить объявление, добавив ключевое слово extern, и предоставить инициализатор. Разве это не то же самое, что определение переменной и предоставление ей инициализатора? Если нет, то почему?

Когда мы используем extern вместе с инициализатором, обычно это происходит потому, что мы пытаемся определить объект const с внешней связью. См. Ниже:

// At global scope:
const int c1 = 42;  // definition with internal linkage
extern const int c2;  // declaration with external linkage
extern const int c3 = 42;  // definition with external linkage
...