是否可以使用聚合初始化来制作指针 aptr
指向a
这是同一个成员 struct
?
struct S {
int a;
int* aptr;
};
int main() {
S s = {
.a = 3,
.aptr = &a //point aptr to a
};
return 0;
}
问题适用于
C
和 C++
.
最佳答案
一个工作初始化将是:
struct S {
int a;
int* aptr;
};
int main() {
struct S s = {.a = 3, .aptr = &s.a};
printf("%d", *s.aptr);
}
工作 sample :C11 GNU
C++2a GNU
关于初始化的正确性:
对于 C:
The evaluations of the initialization list expressions are indeterminately sequenced with respect to one another and thus the order in which any side effects occur is unspecified.
对于 C++:
Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack expansions ([temp.variadic]), are evaluated in the order in which they appear. That is, every value computation and side effect associated with a given initializer-clause is sequenced before every value computation and side effect associated with any initializer-clause that follows it in the comma-separated list of the initializer-list.
然而,尽管我们可以观察到差异,但在这种情况下,表达式的计算顺序似乎并不重要,因为您实际上并没有访问
s.a
的值。 ,只是它的地址,此时可以访问。所以这是 的正确初始化
C
和 C++
.这段代码需要注意的地方,在
MSVC
, 中存在编译错误C++
:use of designated initializers requires at least '/std:c++latest'
使用
std:c++latest
错误更改为:designated and non-designated initializers is nonstandard in C++
但是,范围从 的编译器
clang 3.1
至 clang 10.0
和 gcc 4.9.0
至 gcc 10.0
与 C++03
至 C++2a
编译正常,没有警告。在 中引入的指定初始值设定项
C++20
,所以不接受它们实际上是正确的,因为 MSVC 仍然不接受 /std:c++20
,目前还不能使用,看起来也是gcc
和 clang
始终为这些初始值设定项提供支持。话虽如此,第二个解决方案是:
struct S {
int a;
int* aptr;
};
int main() {
struct S s = { 3, &s.a };
printf("%d", *s.aptr);
}
这个初始化的第二个版本在每个被测试的编译器中都没有问题,所以可以假设它更便携。第一个版本可能更容易阅读,并且可以更容易地识别初始化中的错误,这是指定初始化程序的优点之一。
关于c++ - 聚合初始化,将成员指针设置为相同的结构成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60190650/