Как шаблон влияет на связывание глобальной переменной const? - PullRequest
3 голосов
/ 29 октября 2019

Как указано в документе (выделено мной):

Любое из следующих имен, объявленных в области имен, имеет внутреннюю связь :

  • энергонезависимый не шаблон не встроенный переменные, соответствующие константам (включая constexpr), которые не объявлены extern и ранее не были объявлены как имеющие внешнюю связь;

Так что я ожидаю, что переменные шаблона const будут иметь внешнюю связь. Итак, я сделал тест :

// main.cpp
void other();

template<class T> T var = 1;
template<class T> const T constVar = 1;

int main() {
  std::cout << var<int> << ' ' << constVar<int> << std::endl;
  other();
}

// other.cpp
template<class T> T var = 2;
template<class T> const T constVar = 2;

void other() {
  std::cout << var<int> << ' ' << constVar<int> << std::endl;
}

И вывод:

1 1
1 2

Второй столбец для constVar, и он отличается для разных строк(напечатано из разных переводческих единиц). Это заставляет меня думать, что оно на самом деле имеет внутреннюю связь, несмотря на то, что это шаблон.

Я понимаю, что нарушаю ODR, но только для того, чтобы понять, что происходит.

Так же, как и у constVarвнутренняя связь? Если да, что означает выделенный фрагмент документа? Если нет, то что происходит и зачем нам этот выделенный фрагмент?

1 Ответ

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

C ++ 14 N4296 §14.4

Имя шаблона имеет связь (3.5). [...] Определения шаблонов должны соответствовать правилу one (3.2).

C ++ 14 N4296 §3.2.6

Если такой объект с именем D определен более чем в одной единице перевода, то

  • каждое определение D должно состоять из одной и той же последовательности токенов;[...]

Если D является шаблоном и определен более чем в одной единице перевода, то предыдущие требования должны применяться к именам из области действия шаблона, используемой в определении шаблона (14.6.3), а также к зависимым именам в момент создания (14.6.2). Если определения D удовлетворяют всем этим требованиям, то поведение такое, как если бы было одно определение D. Если определения D не удовлетворяют этим требованиям, то поведение не определено .

Шаблоны неявно встроены, т.е. имеют внешнюю связь. Что происходит = неопределенное поведение. Компилятор не требуется для диагностики вашего кода и может привести к неожиданным / противоречивым результатам.

...