8

抱歉英语不好。

假设代码(C99 或更高版本):

typedef struct {
    int a, b;
} foo_t;

foo_t f = { .a = 1, .b = 2  };

f = (foo_t){ .b = 3 };

现在是什么f.a?C标准对此有什么说法吗?

我知道对于部分初始化,标准保证所有未初始化的成员都将被初始化为“适当的零”(0对于整数、0.0浮点数、NULL指针等)。但是最后一条语句不是初始化(据我所知),因为f它已经存在。我很困惑。

4

2 回答 2

7

C99 标准的第6.5.2.5 节复合文字中的第 6 点指出:

复合文字的值是由初始化列表初始化的未命名对象的值。

foo_t通过您提到的相同规则,未命名的部分被初始化。

最后一条语句是assignment,但复合文字是由初始化列表初始化的未命名对象。意味着赋值后的unnamed.a值为零并且f.a为零。

于 2013-01-08T14:30:48.143 回答
5

在这个表达式中:

f = (foo_t){ .b = 3 };

(foo_t){ .b = 3 }是复合文字,即foo_t类型的左值,已部分初始化。它仍然是部分初始化,所以同样的规则适用:

C11 6.7.9/21:

如果大括号括起来的列表中的初始值设定项少于聚合的元素或成员,或者用于初始化已知大小数组的字符串文字中的字符少于数组中的元素,则聚合的其余部分应隐式初始化与具有静态存储持续时间的对象相同。

只有在复合文字被初始化后,您才能将其分配给f.

这相当于:

foo_t f = { .a = 1, .b = 2  };
foo_t c = { .b = 3 };
f = c;

如果您不熟悉复合文字,GCC 有很好的文档

于 2013-01-08T14:31:27.723 回答