抱歉英语不好。
假设代码(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
{{1}对于指针等)。但最后一个语句不是初始化(据我所知),因为NULL
已经存在。我很困惑。
答案 0 :(得分:6)
C99标准的 6.5.2.5复合文字部分中的第6点:
复合文字的值是初始化列表初始化的未命名对象的值。
根据您提及的相同规则,部分初始化未命名的foo_t
。
最后一个语句是赋值,但是复合文字是由初始化列表初始化的未命名对象。这意味着unnamed.a
的值为零,f.a
在赋值后为零。
答案 1 :(得分:4)
在这个表达式中:
f = (foo_t){ .b = 3 };
(foo_t){ .b = 3 }
是复合文字,即foo_t
类型的左值,已部分初始化。它仍然是部分初始化,因此适用相同的规则:
C11 6.7.9 / 21:
如果括号括起的列表中的初始值设定项少于此值 是聚合的元素或成员,或者是一个或多个字符 string literal用于初始化已知大小的数组 是数组中的元素,聚合的其余部分应为 隐式初始化与具有静态存储的对象相同 持续时间。
只有在复合文字初始化后才将其分配给f
。
它等同于:
foo_t f = { .a = 1, .b = 2 };
foo_t c = { .b = 3 };
f = c;
如果您不熟悉复合文字,GCC has good documentation for it。