Статически инициализировать массив внутри структуры

Не буду говорить за другие компиляторы, но в компиляторе GNU GCC вы можете статически инициализировать массив со следующим синтаксисом:

struct some_struct {
        unsigned *some_array;
} some_var = {
        .some_array = (unsigned[]) { 1u, 2u, 3u, 4u, 5u, },
};

Сначала я встретил этот синтаксис в поисках ответа на вопрос, который меня беспокоил, и пришел к this< /а> ответ. Но я еще не нашел ссылки на справочник GNU, который бы охватывал такой синтаксис.

Я был бы очень признателен, если бы кто-нибудь поделился со мной ссылкой на этот синтаксис. Спасибо!


person mesmerizingr    schedule 13.08.2014    source источник
comment
Это составной литерал, введенный в C99, [подробнее]   -  person David Ranieri    schedule 13.08.2014
comment
@mesmerizingsnow: Что именно вы подразумеваете под статической инициализацией при статической инициализации?   -  person AnT    schedule 14.08.2014
comment
@AndreyT Я не был уверен, пока не получил здесь несколько ответов (включая ваш).   -  person mesmerizingr    schedule 14.08.2014


Ответы (2)


Вы вряд ли найдете много документации GNU по этому вопросу, потому что это не расширение GCC — это часть стандартного синтаксиса C, называемая составным литералом. Он определен в стандарте C, в разделы 6.5.2.5 и 6.7.9 (последний охватывает часть между фигурными скобками, которая одинакова как для составных литералов, так и для статических инициализаторов, поэтому стандарт описывает ее только один раз).

Вы также можете использовать этот синтаксис для описания значений динамических объектов, а не только для статических инициализаций, даже в одиночку в выражении без присвоения какой-либо переменной. Составной литерал может появиться практически везде, где может появиться имя переменной: вы можете передать их функциям, создать их только для доступа к одному элементу, взять их адрес (вы даже можете присвоить им для, хотя это не очевидно как это полезно).

Синтаксис един для всех типов значений C и может использоваться для создания массивов (обозначьте определенные элементы для установки с помощью [N]=), структур и объединений (обозначьте определенные элементы с помощью .field=) и даже числовых типов (без элементов, поэтому не обозначайте, просто поместите значение между фигурными скобками). Синтаксис должен быть простым и согласованным для создания макросов и генераторов кода (в дополнение к элегантности для написания вручную).

person Leushenko    schedule 14.08.2014

Итак, если ваш вопрос касается синтаксиса составного литерала, то одна важная деталь заключается в том, что вы не инициализируете массив внутри структуры. Вы инициализируете указатель внутри структуры. Код, который у вас сейчас есть, формально правильный.

Если бы у вас действительно был массив внутри вашей структуры, то такая инициализация составным литералом не работала бы. Вы не можете инициализировать массив из другого массива. Массивы не копируются (за исключением char инициализации массива из строкового литерала). Однако в этом случае вы сможете использовать обычный инициализатор, заключенный в {}, а не составной литерал.

Также имейте в виду, что время жизни составного литерала (unsigned[]) { 1u, 2u, 3u, 4u, 5u, } определяется областью, в которой он появляется. Если вы сделаете это в локальной области видимости, массив составных литералов будет уничтожен в конце блока. Значение указателя (если вам каким-то образом удастся вывести его за пределы этого блока) станет недействительным.

person AnT    schedule 14.08.2014