c++ - 聚合初始化,将成员指针设置为相同的结构成员

标签 c++ c struct c11 c++20

是否可以使用聚合初始化来制作指针 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 ,目前还不能使用,看起来也是gccclang始终为这些初始值设定项提供支持。
话虽如此,第二个解决方案是:
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/

相关文章:

c++ - ELI5 : What is the data type of `int *p[]`

c++ - ld 找不到 x86_64 架构的 Rcpp 符号

c - C中的管道/FIFO清除

从另一个结构更改一个结构的值

c - 使用指针访问结构成员

c - 结构指针强制转换

c++ - erase-remove_if 习语 - 有什么东西被删除了吗?

C++/RapidXML : Edit node and write to a new XML file doesn't have the updated nodes

C++ 按位异或 ^ 不起作用

c - struct sockadr_in 不应该同时适用于 IPv4 和 IPv6 吗?