Intereting Posts
преобразование массива в строку Объединение двух строк в одну строку, которая исключает одни и те же буквы в C Почему результат этого явного приведения отличается от неявного? Выделите 2-мерный массив в C с фиксированным размером Есть ли точка последовательности между этими назначениями? Как написать отдельные биты в файл в C Как дать подсказку gcc о количестве циклов «Инициализатор не постоянный» для глобальной переменной? Почему объявление main как массива компилируется? Ожидается, что «строка инициализации для массива символов слишком длинная» предупреждение Почему отдельные сообщения UDP всегда опускаются ниже определенного размера буфера? Инициализировать полиморфную переменную на стеке Преобразование «целых строк» ​​в целочисленный массив Как получить список устройств видеозахвата NAMES (веб-камеры) на linux (ubuntu)? (C / C ++) Является ли write () безопасным для вызова из нескольких streamов одновременно?

Является ли память выделенной для статической константной переменной, адрес которой никогда не используется?

Если я никогда не использую адрес статической константной переменной, выделяется ли память для использования при использовании современного современного компилятора?

Это зависит от типа переменной и от того, является ли «константа» также «постоянным выражением». Пример:

static const Foo = get_foo(std::cin); static const int q = argc * 3; static const std::string s(gets()); 

Эти переменные являются const, но наглядно нуждаются в фактическом распределении.

С другой стороны, следующее постоянное выражение может никогда не иметь физического хранилища:

 static const int N = 1000; static const std::shared_ptr vp(); // constexpr constructor! 

Самое главное, переменные- члены static constexpr не нуждаются в определении, если вы будете осторожны:

 struct Bar { int size() const { return N; } static const int N = 8; }; // does NOT need "const int Bar::N;" 

Есть вероятность, что это не так, но это не имеет значения. Вы не можете полагаться на детали реализации, только по стандарту.

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

В дополнение к ограничениям, которые упоминает Kerrek SB , хранилище для значения const expr может быть устранено, если само значение никогда не используется во время выполнения.

Это не обязательно означает, что значение не должно оцениваться – если статическая const expr использовалась только как условие ветвления, это условие может быть оценено статически, а другие пути кода не могут быть сгенерированы или могут быть исключены оптимизатором.

В значительной степени любое хранилище со static продолжительностью может быть устранено, если реализация может гарантировать поведение, как если бы хранилище присутствовало, т. Е. Выражение сравнения, которое может быть оценено во время компиляции, – например, другое const expr , сравнение указателей, в котором известно, что rhs быть псевдонимом другой переменной или, возможно, несовместимым типом. Он также может быть исключен, если значение считывается только в переменные, которые никогда не читаются сами; или где значение может быть уменьшено до const expr .

 struct Foo{}; static Foo bar; // static instance Foo* func() { if ( ! (&bar) ) { // always non-NULL // this block may be eliminated Foo* myCopy(new Foo(bar)); return myCopy; } // so 'bar' is never referred to, and we know it has no side- // effects, so the static variable can be eliminated return new Foo(); } 

3.7.1 Статическая продолжительность хранения

2. Если объект статической продолжительности хранения имеет инициализацию или деструктор с побочными эффектами, он не должен быть исключен, даже если он кажется неиспользованным, за исключением того, что объект classа или его копия могут быть устранены, как указано в 12.8.

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

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

Сказав это, стандарт определяет, можно ли оптимизировать статическое хранилище (3.7.1.2: [basic.stc.static]):

Если переменная со статической продолжительностью хранения имеет инициализацию или деструктор с побочными эффектами, она не должна быть устранена, даже если она не используется, за исключением того, что объект classа или его копирование / перемещение могут быть устранены, как указано в 12.8.

Поэтому, если статическая константная переменная имеет конструктор или деструктор, ее нельзя оптимизировать (хотя некоторые компиляторы / линкеры будут делать это в любом случае). Если это не так, это возможно. Будет ли это зависит от компоновщика.