是否可以使用聚合初始化将aptr
设置为指向同一结构内部的a
?
问题是针对[[C
和C++
。
struct S {
int a;
int* aptr;
};
int main() {
S s = {
.a = 3,
.aptr = &a
};
return 0;
}
struct S {
int a;
int* aptr;
};
int main() {
struct S s = {.a = 3, .aptr = &s.a};
printf("%d", *s.aptr);
}
正在工作的样本
C11 GNU关于初始化的正确性:
对于C:
初始化列表表达式的求值相对于彼此不确定地排序,因此未指定发生任何副作用的顺序。对于C ++:
在大括号-初始列表的初始化列表中,初始化子句,包括由于压缩扩展([temp.variadic])导致的子句,。也就是说,与给定的初始化程序子句相关的每个值计算和副作用在与它之后的任何与初始化程序列表的逗号分隔列表中的任何初始化子句相关联的每个值计算和副作用之前都要进行排序。 但是,尽管有差异,但我们可以观察到:按照它们出现的顺序进行评估
“表达式的计算顺序似乎无关紧要,因为您实际上并没有访问s.a
的值,而只是访问它的地址(此时可以访问它)。”所以这似乎对于
和
C
C++
都是正确的初始化。阅读评论部分,这里将详细讨论。
可能我在MSVC中遇到此代码问题,它给了我一个编译器错误:使用指定的初始化程序至少需要'/ std:c ++ latest'使用
错误更改为:
std:c++latest
指定和未指定的初始化程序在C ++中是非标准的但是,与
和
clang 3.1
C++03 GNU
一样古老的编译器。)>话虽如此,第二种解决方案是:
struct S { int a; int* aptr; }; int main() { struct S s = { 3, &s.a }; printf("%d", *s.aptr); }
初始化的第二个版本在我使用的每个编译器中都可以正常运行,因此可以假设它具有更高的可移植性。第一个版本可能更易于阅读,并且由于明确显示了指定的初始值设定项,因此可以更轻松地识别初始化错误。