Когда оптимизация отключена, ответ зависит от компилятора. Но когда оптимизация включена, конечный результат тот же, независимо от компилятора. Предположим, что оптимизация включена.
Компилятор не будет излучать определение для const static
поля в сгенерированном файле объект, когда оба из следующих условий:
- Это может решить все использование поля с постоянным значением было инициализируются ,
- Существует не более одного файла исходного кода, который использовал это поле (есть исключение, о котором я расскажу в конце).
Ниже я расскажу о втором условии. Но теперь давайте сосредоточимся на первом. Давайте посмотрим пример. Предположим, что целевая платформа 32-бит, и мы определили следующий тип:
// In MyClassA.h
class MyClassA{
public:
const static int MyClassAField;
};
// In MyClassA.cpp (or in MyClassA.h if it was included in at most one cpp file)
const int MyClassA::MyClassAField = 2;
Большинство компиляторов считают int
быть 32-разрядное целое число. Поэтому на 32-битном процессоре большинство инструкций могут обрабатывать 32-битную константу. В этом случае компилятор сможет заменить любое использование MyClassAField
с константой 2, и это поле не будет существовать в объектном файле.
С другой стороны, если поле было типа double
, то на 32-битной платформе инструкции не могут обрабатывать 64-битные значения. В этом случае большинство компиляторов испускает поле в объектном файле и использует инструкции SSE и записывает их в 64-разрядное значение из памяти и обрабатывает их.
Теперь я объясню второе условие. Если имеется более одного файла исходного кода, использующего это поле, его нельзя устранить (независимо от того, включено ли Whole Program Optimization (WPO) или нет), поскольку в каком-либо объектном файле должно быть указано определение поля, чтобы компоновщик мог использовать его для других объектных файлов. Однако компоновщик, если вы указали правильный переключатель, может исключить поле из сгенерированного двоичного файла.
Эта оптимизация компоновщика включена с /OPT:REF для VC++ и --gc-sections для gcc. Для icc имена коммутаторов одинаковы (/ OPT: REF в Windows и --gc-разделы в Linx и OSX). Однако компилятор должен испускать каждую функцию, статическое или глобальное поле в отдельном разделе в объектном файле, чтобы компоновщик мог его устранить.
Однако есть улов. Если поле было определенно рядной следующим образом:
class MyClassA{
public:
const static int MyClassAField = 2;
};
Тогда компилятор сам устранит определение этого поля из каждого объектного файла, который его использует. Это потому, что каждый файл исходного кода, который его использует, включает в себя отдельное определение. Каждый из них компилируется отдельно, сам компилятор оптимизирует поле, используя оптимизацию, называемую постоянным распространением. Фактически компилятор VC++ выполняет эту оптимизацию, даже если оптимизация отключена.
Когда оптимизация отключена, будет ли поле const static
исключено или не зависит от компилятора, но, вероятно, оно не будет устранено.
Я считаю, что вы действительно можете проверить это, экспериментируя. Если вы не спрашиваете, разрешено ли это * стандарту, но тогда этого не хватает [tag: language-lawyer]. – Griwes
Как вы узнаете, была ли она оптимизирована? Какая разница в программе? – Barmar
@Barmar: вы можете посмотреть файл с листингами языка ассемблера, сгенерированный компилятором для сборки релиза. – User5910