C - 创建匿名结构实例

Jet*_*lue 11 c struct compound-literals

此代码中,结构定义如下:

typedef struct
{
    int line;
    int column;
} Pos;
Run Code Online (Sandbox Code Playgroud)

后来用这种方式:

Pos get_pos ( int delta )
{
    ...

    return ( Pos ){ f->line, f->column + delta };
}
Run Code Online (Sandbox Code Playgroud)

该行return ( Pos ){ f->line, f->column + delta }似乎是Pos使用初始化值创建结构的匿名实例.这种技术被称为什么?它是如何工作的?我在哪里可以了解更多信息?

dbu*_*ush 10

这称为复合文字,并在C标准的 6.5.2.5节中记录.

本节摘录如下:

3后缀表达式由带括号的类型名称后跟括号括起的初始值设定项列表组成,是一个 复合文字.它提供了一个未命名的对象,其值由初始化列表给出.

4如果类型名称指定了未知大小的数组,则大小由6.7.9中指定的初始化程序列表确定,复合文字的类型是已完成数组类型的类型.否则(当类型名称指定对象类型时),复合文字的类型是由类型名称指定的类型.在任何一种情况下,结果都是左值.

5复合文字的值是初始化列表初始化的未命名对象的值.如果复合文字出现在函数体外,则该对象具有静态存储持续时间; 否则,它具有与封闭块相关的自动存储持续时间.

在您的情况下,复合文字用于a struct,但也可以为数组创建它们.第8段举了一个例子:

8 示例1文件范围定义

int *p = (int []){2, 4};
Run Code Online (Sandbox Code Playgroud)

初始化p指向两个整数数组的第一个元素,第一个元素的值为2,第二个元素的值为4.此复合文字中的表达式必须是常量.未命名的对象具有静态存储持续时间.

另请注意,复合文字是左值,这意味着您可以获取其地址:

Pos *p = &( Pos ){ f->line, f->column + delta };
Run Code Online (Sandbox Code Playgroud)

此对象具有与其范围关联的生命周期,这意味着一旦范围结束,该对象就不再存在.因此,在超出范围后不要随身携带.

您还可以将复合文字与指定的初始值设定项一起使用:

return ( Pos ){ .line=f->line, .column=f->column + delta };
Run Code Online (Sandbox Code Playgroud)