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

熊孩纸 阅读:34 2025-02-15 21:57:57 评论:0

是否可以使用聚合初始化来制作指针 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++
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号