Должен ли я добавить ключевое слово `extern` к определению константы для общего доступа к исходным файлам? - PullRequest
0 голосов
/ 24 января 2019

В «Учебнике по С ++, пятое издание» на стр. 95. Говоря о константах. Он сказал:

Иногда у нас есть переменная const, которую мы хотим использовать в нескольких файлах, но инициализатор которой не является константным выражением. В этом случае мы не хотим, чтобы компилятор генерировал отдельную переменную в каждом файле. Вместо этого мы хотим, чтобы объект const вел себя как другие (не const) переменные. Мы хотим определить const в одном файле и объявить его в других файлах, которые используют этот объект.

Чтобы определить отдельный экземпляр переменной const, мы используем ключевое слово extern как для ее определения, так и для объявления (ей):

// file_1.cc определяет и инициализирует const, который доступен для других файлов.

extern const int bufSize = fcn();

// file_1.h

extern const int bufSize; // same bufSize as defined in file_1.cc

В чем я не уверен, так это в последнем абзаце; Я удалил extern из определения bufsize, но это нормально и доступно из других файлов?!

const int bufSize = fcn(); // without keyword extern

Почему он сказал, что мы должны добавить ключевое слово extern в оба объявления и определение bufsize, чтобы они были доступны из других файлов, но extern, как мне кажется, достаточно в объявлениях?

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 24 января 2019

Вы правы, что extern не требуется в файле cpp.

Во-первых, вам необходимо понять, что такое объявление и определение.Вашему bufSize требуется объявление в каждой используемой единице перевода и одно определение внутри вашей программы.Итак, давайте посмотрим, что у вас есть в файле .h:

extern const int bufSize;

Это допустимое объявление переменной const int.Здесь нет путаницы.

Теперь вам нужно определение, которое идет в файл .cpp, и вам нужно убедиться, что оно существует в одном месте во всей программе, иначе вы нарушаете ODR - One DefinitionПравило.Вот что у вас сейчас есть:

extern const int bufSize = fcn();

Это допустимое определение, поскольку любое объявление с внешним классом хранения и инициализатором является определением.Тем не менее,

const int bufSize = fcn();

также является определением.А с предыдущим объявлением extern это определение имеет внешнюю связь - это означает, что к нему можно получить доступ из других единиц перевода (без этого const int bufSize в области пространства имен будет иметь внутреннюю связь).

Bottomстрока - extern в этом примере не влияет на поведение компилятора, но напоминает всем, кто читает код, что переменная имеет внешнюю связь (как это не сразу видно из этой строки).

Дальнейшее чтение:

https://en.cppreference.com/w/cpp/language/definition

https://en.cppreference.com/w/cpp/language/storage_duration

...