后缀表达式 (type-name){initializer-list}

Postfix expression (type-name){initializer-list}

6.5.2.5/4 部分对 ( type-name ) { initializer-list } 形式的 postfix-expression 进行了解释。这是:

If the type name specifies an array of unknown size, the size is determined by the initializer list as specified in 6.7.9, and the type of the compound literal is that of the completed array type. Otherwise (when the type name specifies an object type), the type of the compound literal is that specified by the type name. In either case, the result is an lvalue.

我不明白措辞the type of the compound literal。文字怎么可能有类型呢?对应的未命名对象的类型是不是the type of the compound literal的意思?

例如

long long *longs = (long long []) {1333, 3123, 3, 122};

这里的initializer-list用来初始化一个long long [4]类型的无名对象。

也不清楚In either case, the result is an lvalue的目的是什么。在 assignment-expression 中使用时,lvalue conversion 对右操作数执行,因此它不再是左值。

据推测,"compound literal" 表示使用 "compound literal" 语言结构指定的 object/value。 Values/objects 在 C 中有类型。

使复合文字成为左值的目的是这样的代码 int *x = &(int){42}; *x = 43; 有效。它使复合文字的行为有点像匿名变量。 (虽然不完全是。与常规变量不同,复合文字不能存储 class 说明符,我个人认为这是语言缺陷。)

复合字面量的主要目的是提供一个匿名对象,这样你就可以拥有一个指向真实对象的指针,而无需先创建一个变量。

它是一个左值,也就是说可以得到它的地址。但是,它不是可修改的左值,就像一个普通的数组对象:

int a[] = {0, 0};
a = {1, 2}; // error, a is not a modifiable lvalue

当然,您可以使用下标运算符或间接指针访问来修改它:

a[0] = 1; // fine
(long long []) {1333, 3123, 3, 122}[0] = 1; // fine as well