Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: mesmerizingrОтветов: 2

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

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

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

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

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

gcccarraysinitializationgnu

Ответы

Ответ 1 · рейтинг 1 · Leushenko

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

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

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

Ответ 2 · рейтинг 2 · AnT

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

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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы