Почему я могу включить заголовочный файл в несколько файлов cpp, который содержит const int и не имеет ошибки компилятора? - PullRequest
3 голосов
/ 02 апреля 2012

Давайте предположим, что у меня есть файлы a.cpp b.cpp и файл c.h. Оба файла cpp содержат файл c.h. Заголовочный файл содержит набор определений const int, и когда я их компилирую, я не получаю ошибок, и все же я могу получить доступ к этим const, как если бы они были глобальными переменными. Итак, вопрос, почему я не получаю никаких ошибок компиляции, если у меня есть несколько определений const, а также у этих const int глобальная область видимости?

Ответы [ 4 ]

5 голосов
/ 02 апреля 2012

Это потому, что объявление const в области именного пространства подразумевает внутреннюю связь. Объект с внутренней связью доступен только в пределах единицы перевода, в которой он определен. Таким образом, в некотором смысле, один const объект, который у вас есть в c.h, на самом деле является двумя разными объектами, один внутренний для a.cpp и один внутренний для b.cpp.

Другими словами,

const int x = ...;

эквивалентно

static const int x = ...;

, а

int x;

похож на

extern int x;

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

Обратите внимание, что это относится к C ++. В C const не изменяет подразумеваемую связь. Причина в том, что комитет C ++ хотел, чтобы вы могли написать

const int x = 5;

в шапке. В C этот заголовок, включенный в несколько файлов, может вызвать ошибки компоновщика, потому что вы будете определять один и тот же объект несколько раз.

2 голосов
/ 02 апреля 2012

Из текущего стандарта C ++ ...

7.1.1 Спецификаторы класса хранения

7) Имя, объявленное в области пространства имен без спецификатора класса хранения, имеет внешнюю связь, если оно не имеет внутренней связи из-за предыдущего объявления и при условии, что оно не объявлено как const. Объекты, объявленные const и явно не объявленные extern, имеют внутреннюю связь.

3.5 Программа и связь

2) Когда имя имеет внутреннюю связь , обозначаемая им сущность может именоваться именами из других областей в той же единице перевода .

Препроцессор заставляет вещи, определенные в заголовках, быть включенными в текущую единицу перевода.

0 голосов
/ 02 апреля 2012

Реальная причина: потому что #define является злом и должен умереть.

Некоторые использования #define можно заменить встроенными функциями.Некоторые - с const объявлениями переменных.Поскольку #define, как правило, находится в заголовочных файлах, его замена на const s работает лучше.Таким образом, правило «по умолчанию является статическим».

0 голосов
/ 02 апреля 2012

При этом вы создаете отдельную переменную const в каждом объектном файле для каждой константы в заголовке.Это не проблема, так как они const.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...