Почему const влияет на связь экземпляра шаблона глобальной переменной в gcc? - PullRequest
2 голосов
/ 29 октября 2019

Я беру адреса следующих экземпляров шаблонов переменных из двух блоков перевода:

template<class T> bool b = true;
template<class T> const bool cb = true;
template<class T> inline const bool icb = true;

Я печатаю адреса b<int>, cb<int> и icb<int>. Вот что говорит clang :

0x6030c0 0x401ae4 0x401ae5  // first translation unit
0x6030c0 0x401ae4 0x401ae5  // second translation unit

Все адреса совпадают, что-то ожидаемое. И вот что gcc говорит :

0x6015b0 0x400ef5 0x400ef4  // first translation unit
0x6015b0 0x400ef6 0x400ef4  // second translation unit

Адрес cb<int> изменяется. А? Это ошибка? Если нет, то может кто-нибудь объяснить мне этот эффект?

Ответы [ 2 ]

2 голосов
/ 29 октября 2019

Мне кажется, это связано с CWG Issue 1713 :

Связывание специализаций с переменными шаблонами

Учитывая объявление области имен пространства, например

template<typename T> T var = T();

должен ли T<const int> иметь внутреннюю связь в силу своего типа с константой? Или он должен наследовать связь шаблона?

Примечания к февральскому совещанию 2014 года :

CWG отметила, что связь осуществляется по имени и специализации переменнойУ шаблона нет имени, отдельного от имени шаблона переменной, поэтому специализация будет иметь связь с шаблоном.

Кажется, что Clang следует за ним. Имя шаблона имеет внешнюю связь, как и переменная. Он указан для обычных переменных, но шаблоны - это другой зверь.

1 голос
/ 29 октября 2019

Из стандарта C ++ (6.5 Программа и связь)

3 Имя, имеющее область пространства имен (6.3.6), имеет внутреннюю связь, если это имя

(3.2) - не встроенная переменная энергонезависимого const-квалифицированного типа, который явно не объявлен как extern или ранее не объявлен как имеющий внешнюю связь ;или

Таким образом, специализация шаблона переменной cb имеет внутреннюю связь. Это означает, что его адрес может быть разным в разных единицах компиляции.

...