Spec-Zone.ru › GCC 15

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

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

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

Чтобы задать индекс массива, укажите ‘[index] =’ перед значением элемента. Например,

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

эквивалентно следующему:

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

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

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

Чтобы инициализировать диапазон элементов одним и тем же значением, укажите ‘[first ... last] = value’. Это расширение GNU. Например,

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

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

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

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

struct point { int x, y; };

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

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

эквивалентна следующей:

struct point p = { xvalue, yvalue };

Другой синтаксис с тем же значением, устаревший с GCC 2.5, — ‘fieldname:’, как показано здесь:

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

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

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

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

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

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

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

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

Spec-Zone.ru

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