Поиск…


Синтаксис

  • (тип) {initializer-list}

замечания

Стандарт C говорит в C11-§6.5.2.5 / 3:

Постфиксное выражение, состоящее из имени типа в скобках, за которым следует скопированный список инициализаторов, является сложным литералом . Он предоставляет неназванный объект, значение которого задается в списке инициализаторов. 99)

и сноска 99 гласит:

Обратите внимание, что это отличается от литого выражения. Например, приведение задает преобразование только в скалярные типы или только void , а результат литого выражения не является значением lvalue.

Обратите внимание, что:

Строковые литералы и составные литералы с категориальными типами, не обязательно обозначают разные объекты. 101)

101). Это позволяет реализациям совместно использовать хранилище для строковых литералов и постоянных составных литералов с одинаковыми или перекрывающимися представлениями.

Пример приведен в стандарте:
С11-§6.5.2.5 / 13:

Подобно строковым литералам, const-квалифицированные составные литералы могут быть помещены в постоянную память и могут быть разделены. Например,

(const char []){"abc"} == "abc"

может дать 1, если хранилище литералов разделено.

Определение / Инициализация сложных литералов

Комбинированный литерал является неназванным объектом, который создается в области, где определено. Концепция была впервые введена в стандарте C99. Примером для составного литерала является

Примеры из стандарта C, C11-§6.5.2.5 / 9:

int *p = (int [2]){ 2, 4 };

p инициализируется адресом первого элемента неназванного массива из двух целых чисел.

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

void f(void)
{
    int *p;
    /*...*/
    p = (int [2]){ *p };
    /*...*/
}

p присваивается адрес первого элемента массива из двух ints, первый из которых имеет значение, ранее указанное p а второе - ноль. [...]

Здесь p остается действительным до конца блока.

Комбинированный литерал с указателями

(также от C11)

  struct point {
    unsigned x;
    unsigned y;
  };

  extern void drawline(struct point, struct point);

 // used somewhere like this
 drawline((struct point){.x=1, .y=1}, (struct point){.x=3, .y=4});

drawline функция drawline получает два аргумента типа struct point . Первый имеет координаты x == 1 и y == 1 , тогда как второй имеет x == 3 и y == 4

Составной литерал без указания длины массива

int *p = (int []){ 1, 2, 3};  

В этом случае размер массива не указан, тогда он будет определяться длиной инициализатора.

Составной литерал, имеющий длину инициализатора меньше указанного размера массива

int *p = (int [10]){1, 2, 3}; 

остальные элементы составного литерала будут инициализированы до 0 неявно.

Только для чтения составной литерал

Обратите внимание, что составной литерал является lvalue, и поэтому его элементы могут быть модифицируемыми. Литерал соединения только для чтения может быть указан с использованием спецификатора const as (const int[]){1,2} .

Комбинированный литерал, содержащий произвольные выражения

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

void foo()
{
    int *p;
    int i = 2; j = 5;
    /*...*/
    p = (int [2]){ i+j, i*j };
    /*...*/
}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow