Spec-Zone.ru › GCC 9

6.29 Инициализаторы с указанием места

Стандарт C90 требует, чтобы элементы инициализатора появлялись в фиксированном порядке, таком же, как порядок элементов в массиве или структуре, которые инициализируются.

В ISO C99 вы можете указать элементы в любом порядке, указав индексы массива или имена полей структуры, к которым они относятся, а GNU C разрешает это в режиме C90 также как расширение. Это расширение не реализовано в GNU C++.

Для указания индекса массива запишите ‘[индекс] =’ перед значением элемента. Например,

int a[6] = { [4] = 29, [2] = 15 };

эквивалентно

int a[6] = { 0, 0, 15, 0, 29, 0 };

Значения индексов должны быть константными выражениями, даже если массив, который инициализируется, является автоматическим.

Альтернативный синтаксис для этого, устаревший с GCC 2.5, но всё ещё принимаемый GCC, заключается в записи ‘[индекс]’ перед значением элемента без ‘=’.

Для инициализации диапазона элементов одним значением запишите ‘[первый ... последний] = значение’. Это расширение GNU. Например,

int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

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

Обратите внимание, что длина массива — это наибольшее указанное значение плюс один.

В инициализаторе структуры укажите имя поля для инициализации с помощью ‘.имя_поля =’ перед значением элемента. Например, с учетом следующей структуры,

struct point { int x, y; };

следующая инициализация

struct point p = { .y = yvalue, .x = xvalue };

эквивалентна

struct point p = { xvalue, yvalue };

Другой синтаксис, имеющий то же значение, устаревший с GCC 2.5, это ‘имя_поля:’, как показано здесь:

struct point p = { y: yvalue, x: xvalue };

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

‘[индекс]’ или ‘.имя_поля’ известны как указатель. Вы также можете использовать указатель (или устаревший синтаксис двоеточия) при инициализации объединения, чтобы указать, какой элемент объединения следует использовать. Например,

union foo { int i; double d; };

union foo f = { .d = 4 };

преобразует 4 в double для хранения в объединении с использованием второго элемента. В отличие от этого, приведение 4 к типу union foo хранит его в объединении как целое число i, так как это целое число. См. Преобразование в объединение.

Вы можете объединить эту технику именования элементов с обычной C-инициализацией последовательных элементов. Каждый элемент инициализатора, который не имеет указателя, относится к следующему последовательному элементу массива или структуры. Например,

int a[6] = { [1] = v1, v2, [4] = v4 };

эквивалентно

int a[6] = { 0, v1, v2, 0, v4, 0 };

Именование элементов инициализатора массива особенно полезно, когда индексы являются символами или относятся к типу enum. Например:

int whitespace[256]
  = { [' '] = 1, ['\t'] = 1, ['\h'] = 1,
      ['\f'] = 1, ['\n'] = 1, ['\r'] = 1 };

Вы также можете записать ряд ‘.имя_поля’ и ‘[индекс]’ указателей перед ‘=’, чтобы указать вложенный подобъект для инициализации; список берётся относительно подобъекта, соответствующего ближайшей окружающей паре фигурных скобок. Например, со ‘struct point’ декларацией выше:

struct point ptarray[10] = { [2].y = yv2, [2].x = xv2, [0].x = xv0 };

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

Далее: Диапазоны значений, Предыдущее: Составные литералы, Вверх: Расширения C [Оглавление][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-9.5.0/gcc/Designated-Inits.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API