C - 创建匿名结构体实例

13
这段代码中,定义了一个结构体如下:

typedef struct
{
    int line;
    int column;
} Pos;

后来被这样使用:

Pos get_pos ( int delta )
{
    ...

    return ( Pos ){ f->line, f->column + delta };
}
该行代码创建了一个带有初始化值的匿名结构体Pos实例。这种技术被称为结构体字面量(Struct Literals)或者复合字面量(Compound Literals),你可以在C语言标准规范中学习更多相关知识。

7
自C99以来,“复合字面量”(Compound literal)成为了C语言中的一个新特性。 - Amadan
4
C11标准-6.5.2.5复合字面量:该标准介绍了一种创建具有自动存储期限制的匿名对象的方法,即复合字面量。它允许在需要对象的地方直接创建和初始化对象,然后可以像其他普通对象一样使用。 - David C. Rankin
https://stackoverflow.com/questions/tagged/compound-literals+c?sort=votes似乎没有一个标准问题,也许这个可以成为它。 - M.M
谢谢!已经相应地更新了问题标签。 - Jet Blue
1个回答

12
这被称为复合字面量,在C标准6.5.2.5节中有记录。该章节的摘录如下:
3.后缀表达式由带括号的类型名称和由大括号括起来的初始化程序列表组成,是复合字面量。它提供了一个未命名对象,其值由初始化程序列表给出。
4.如果类型名称指定大小未知的数组,则大小由初始化程序列表根据6.7.9指定,并且复合文字的类型为已完成的数组类型。否则(当类型名称指定对象类型时),复合文字的类型为所指定的类型名称。在任一情况下,结果都是lvalue。
5.复合文字的值是由初始化程序列表初始化的未命名对象的值。如果复合文字出现在函数体之外,则该对象具有静态存储持续时间;否则,它具有与封闭块相关联的自动存储持续时间。
在您的情况下,复合文字用于struct,但也可以为数组创建复合文字。第8段给出了一个示例:
8.示例1文件范围定义
int *p = (int []){2, 4};

初始化p,使其指向一个由两个整数组成的数组的第一个元素,其中第一个整数为2,第二个整数为4。这个复合字面量中的表达式必须是常量。未命名对象具有静态存储期。

还要注意,复合字面量是左值,这意味着您可以获取它的地址:

Pos *p = &( Pos ){ f->line, f->column + delta };

这个对象的生命周期与其作用域相关联,也就是说一旦作用域结束,该对象就不存在了。因此,在它超出作用域之后不要携带它的地址。

您还可以使用带有指定初始化程序的复合字面量:

return ( Pos ){ .line=f->line, .column=f->column + delta };

那么它适用于所有类型(不仅仅是聚合类型)吗? - Some Name
1
事实证明是这样的。int x = (int){4};可以编译,尽管对于基本类型使用它没有太多用处。 - dbush

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接