Есть ли способ условно инициализировать глобальную статическую переменную?

#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}, };  

но этот набор флагов происходит во время выполнения

Использование ввода во время выполнения не позволяет инициализировать статические объекты. Вам придется изменить массив после инициализации с помощью операции присваивания.