GCC 和 Clang 都允许指定的初始化器引用正在初始化的结构或数组的成员,但这是合法且定义明确的行为吗?
以下代码示例针对 GCC 和 Clang 进行编译和运行并输出{ .a = 3, .b = 6, }
在这两种情况下:
#include <stdio.h>
typedef struct
{
int a;
int b;
} foo;
int main()
{
foo bar = {
.a = 3,
.b = bar.a + 3,
};
printf("{ .a = %d, .b = %d, }\n", bar.a, bar.b);
return 0;
}
GCC 生成以下输出(编译器资源管理器链接)对于指定的初始化,这表明该操作对于本示例来说是安全的:
mov dword ptr [rbp - 4], 0
mov dword ptr [rbp - 16], 3
mov eax, dword ptr [rbp - 16]
add eax, 3
mov dword ptr [rbp - 12], eax
第 6.7.8 条C99 规范草案讨论了这一点,但我不明白它如何以某种方式定义这种行为。
特别是,第 19 点表明初始化按指定的顺序发生,但第 23 点提到了具有未指定顺序的副作用。我不确定写入结构的数据是否被视为副作用。
- 初始化应按初始值设定项列表顺序进行,为特定子对象提供的每个初始值设定项将覆盖同一子对象的任何先前列出的初始值设定项;所有未显式初始化的子对象应与具有静态存储持续时间的对象一样隐式初始化。
- 初始化列表表达式中任何副作用发生的顺序未指定