Любая потенциальная опасность, используя константы в заголовочных файлах C ++ и спрашивая их адреса в программе - PullRequest
0 голосов
/ 29 сентября 2018

Я определяю константы в заголовочном файле и в том числе в исходных файлах моего проекта.Компилятор C ++ обычно не создает хранилище для этих констант и сохраняет их связь как внутреннюю.Если я запрашиваю адрес какой-либо константы в моей программе, компилятор будет вынужден создать хранилище для этой константы.Мой вопрос: если компилятор создает хранилище для постоянной переменной, будет ли затронуто связывание переменной?Потому что, если связь становится внешней, я получаю ошибки связывания во время компиляции.Моя тестовая программа не выдает никакой ошибки компоновки, когда я указываю указатель на константу включенного заголовочного файла (которому нужен адрес константы).Я буду признателен, если кто-нибудь сможет кратко объяснить концепции хранения и связи в C ++ или направит меня к какому-нибудь хорошему объяснению, доступному где-нибудь.Заранее спасибо.

//in constants.h
const double UNIT_LENGTH = 1e-10;
//in constants.cpp
#include "constants.h"
const double * temp = &UNIT_LENGTH;
//in main
#include "constants.h"
double A = UNIT_LENGTH;  //why there is no linking error

Ответы [ 2 ]

0 голосов
/ 29 сентября 2018

Связывание глобальных константных переменных в C ++ (в отличие от C) определено как всегда внутреннее (то есть статическое).Так что проблемы, которой вы боитесь, не произойдет.

Совсем наоборот.Если бы вы рассматривали глобальную константу как обычную глобальную переменную, вы бы вызвали ошибок компоновщика .

(Но учтите, что если это char * переменные, они должны бытьconst char * const, а не только const char *. Аналогично для других указателей, но чаще всего используются символы.)

0 голосов
/ 29 сентября 2018

У переменных с константой есть внутренняя связь.В стандарте 2012 года в 3.5 / 3 используется формулировка

Имя, имеющее область имен (3.3.6), имеет внутреннюю связь, если оно является именем [...]

  • переменная, которая явно объявлена ​​как const или constexpr и ни явно не объявлена ​​как extern, ни ранее объявлена ​​как имеющая внешнюю связь

«Область пространства имен» включает в себя глобальное пространство имен.

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

...