#c #static-initialization
Вопрос:
Итак, мой текущий код выглядит следующим образом:
static Item fields[] = { {GROUP1, TEXT1}, {GROUP2, 0}, }
Теперь мне нужно внести изменения таким образом, чтобы я инициализировал GROUP2 только в том случае, если выполнено определенное условие, иначе необходимо инициализировать с помощью GROUP3. Поэтому я попробовал следующее:
static Item fields[] = (flagSet)? { {GROUP1, TEXT1}, {GROUP2, 0}, } : { {GROUP1, TEXT1}, {GROUP3, 0}, }
Но это не сработало. Я знаю, что один из способов-использовать макросы #ifdef, но этот набор флагов происходит во время выполнения, и на основе этого мне нужно инициализировать статический массив. Кроме того, поскольку статическая инициализация происходит раньше всего, возможно ли вообще это сделать?
Комментарии:
1. Если это глобальная переменная, ключевое
static
слово, по-видимому, не имеет отношения к вопросу. Глобальные переменные инициализируются перед входом в функциюmain
, независимо от того, являются они статическими или нет.2. Да, это глобальная переменная. Не является частью какого-либо класса или функции.
3. Совершенно непонятно, что вам действительно нужно! Если ваш флаг не является значением препроцессора или константой времени компиляции, а вычисляется во время выполнения, я понятия не имею, за какое время до main это должно произойти! Единственный промежуток времени, когда ваш флаг инициализируется перед основной и перед переменной fields. Позаботьтесь о фиаско со статическим порядком инициализации! И даже если это статическая глобальная переменная, вы также можете изменить содержимое позже. Какую реальную проблему вы хотите решить?
4. Глобальные переменные инициализируются до всего остального в приложении, задолго до
flagSet
того, как будет известно значение. Лучше всего инициализировать массив до некоторого нейтрального значения и отредактировать его послеflagSet
, возможно, также вApp::InitInstance()
.5. Действительно ли это должно быть глобальным? Статика области действия функции инициализируется при первом вызове функции, поэтому тривиальная функция
autoamp; getFields() { fields[] = ...; return fields; }
задержит инициализацию до первого использования.
Ответ №1:
Есть ли способ условно инициализировать глобальную статическую переменную?
ДА. Способы в значительной степени аналогичны условной инициализации неглобальной нестатической переменной.
Однако вы не можете условно инициализировать массив. Вам не помешало бы немного косвенности:
static Item fields_true[] { {GROUP1, TEXT1}, {GROUP2, 0}, }; static Item fields_false[] = { {GROUP1, TEXT1}, {GROUP3, 0}, }; static autoamp; fields = flagSet ? fields_true : fields_false;
Или вы можете инициализировать элементы массива условно. Поскольку разница есть только в одном элементе, в этом случае даже нет никакого повторения:
static Item fields[] = { {GROUP1, TEXT1}, {flagSet ? GROUP2 : GROUP3, 0}, };
но этот набор флагов происходит во время выполнения
Использование ввода во время выполнения не позволяет инициализировать статические объекты. Вам придется изменить массив после инициализации с помощью операции присваивания.