Возможно ли иметь уникальный адрес, выделенный для переменной constexpr, то есть одинаковый для всех единиц перевода, где эта переменная доступна (обычно через заголовок)? Рассмотрим следующий пример:
// foo.hh
#include <iostream>
constexpr int foo = 42;
// a.cc
#include "foo.hh"
void a(void) { std::cout << "a: " << &foo << std::endl; }
// b.cc
#include "foo.hh"
extern void a(void);
int main(int argc, char** argv) {
a();
std::cout << "b: " << &foo << std::endl;
}
Компилируя a.cc
и b.cc
по отдельности и связывая их вместе с помощью gcc 4.7, я вижу два напечатанных адреса. Если я добавлю ключевое слово extern
в заголовок, я получу ошибку компоновщика duplicate symbol _foo in: a.o and b.o
, что меня немного удивило, потому что я думал, что добавление extern
с большей вероятностью заставит компилятор импортировать этот символ из другого объекта, а не экспортировать его из текущего объекта. . Но, похоже, мое понимание того, как все работает, было неправильным.
Есть ли разумный способ объявить constexpr в одном заголовке, чтобы все единицы перевода могли использовать его в своих константных выражениях и чтобы все единицы перевода согласовывали адрес этого символа? Я ожидалось бы, что какой-то дополнительный код будет обозначать единую единицу перевода, которой на самом деле принадлежит этот символ, точно так же, как с переменными extern
и не-extern
без constexpr
.
foo
имеет внутреннюю связь, поэтому вы видите две отдельные копии. Обычное решение вашей проблемы состоит в том, чтобы объявитьextern const int foo
в заголовке и реализовать какconst int foo = 42;
в одной единице перевода. Но тогда очевидно, что это не может быть константное выражение, посколькуint a[foo]
должно быть разрешимым во время компиляции, а не только во время компоновки. - person Kerrek SB   schedule 14.02.2013constexpr
в целом. У меня была привычка использовать внешнюю связь дляconst
глобальных переменных, чтобы избежать дублирования выделения памяти, даже если кто-то решит взять адрес такого зверя. Теперь сconstexpr
это больше не кажется возможным. Так что я на самом деле пытаюсь выяснить, есть ли способ избежать дублирования данных, даже если какой-то странный код, который я сейчас не могу себе представить, решит взять адреса этих вещей повсюду. - person MvG   schedule 14.02.20134 + 4
вообще включает в себя выделение памяти. - person Luc Danton   schedule 14.02.2013