Spec-Zone.ru › GCC 8

6.27 Определяющие инициализаторы

Стандарт 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-8.5.0/gcc/Designated-Inits.html

Spec-Zone.ru

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