简体   繁体   English

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

[英]Aggregate initialization, set member pointer to same struct member

Is it possible to use aggregate initialization to make a pointer aptr point to a which is a member of the same struct ?是否有可能使用集合初始化,使指针aptra是相同的成员struct

struct S {
  int a;
  int* aptr;
};

int main() {
  S s = {
    .a = 3,
    .aptr = &a //point aptr to a
  };
  return 0;
}

The question is for both C and C++ .问题是针对CC++

A working initialization would be:一个工作初始化将是:

struct S {
  int a;
  int* aptr;
};

int main() {
    struct S s = {.a = 3, .aptr = &s.a};
    printf("%d", *s.aptr);
}

Working samples:工作样本:

C11 GNU C11 GNU

C++2a GNU C++2a GNU

Regarding the correctness of the initialization:关于初始化的正确性:

For C:对于 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.初始化列表表达式的计算相对于彼此是不确定的,因此任何副作用发生的顺序是不确定的。

For C++:对于 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 .在花括号初始化器列表的初始化器列表中,初始化器子句,包括任何由包扩展( [temp.variadic] )产生的结果,按它们出现的顺序进行评估 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 .也就是说,与给定的初始化子句相关联的每个值计算和副作用在与在初始化器列表的逗号分隔列表中跟随它的任何初始化子句相关联的每个值计算和副作用之前排序

However, despite the differences we can observe, the order in which the expressions are evaluated does not seem matter in this case, since you're not actually accessing the value of sa , just its address which is accessible at this point.但是,尽管我们可以观察到差异,但在这种情况下,表达式的计算顺序似乎并不重要,因为您实际上并没有访问sa的值,而只是访问了此时可访问的地址。

So this is a correct initialization both for C and C++ .所以这对于CC++都是正确的初始化。


Something to note with this code, in MSVC , there is a compilation error in C++ :这段代码需要注意的是,在MSVC ,在C++有一个编译错误:

 use of designated initializers requires at least '/std:c++latest'

Using std:c++latest the error changes to:使用std:c++latest错误更改为:

 designated and non-designated initializers is nonstandard in C++

However, compilers that range from clang 3.1 to clang 10.0 and gcc 4.9.0 to gcc 10.0 with C++03 to C++2a compile fine with no warnings.但是,从clang 3.1clang 10.0gcc 4.9.0gcc 10.0编译器, C++03C++2a编译得很好,没有警告。

Designated initializers where introduced in C++20 , so it is actually correct not to accept them, as MSVC still does not accept /std:c++20 , it is not possible to use them yet, it also looks like gcc and clang always provided support for these initializers.C++20中引入的指定初始值设定项,所以不接受它们实际上是正确的,因为 MSVC 仍然不接受/std:c++20 ,还不能使用它们,它看起来也像gccclang始终为这些初始值设定项提供支持。

That being said, a second solution would be:话虽如此,第二个解决方案是:

struct S {
    int a;
    int* aptr;
};

int main() {
    struct S s = { 3, &s.a };
    printf("%d", *s.aptr);
}

This second version of initialization compiles with no issues in every compiler tested, so it's fair to assume that it is more portable.这个初始化的第二个版本在每个被测试的编译器中都没有问题,所以可以假设它更便携。

The first version is probably more easily readable and allows for a easier identification of errors in initialization, one of the advantages of designated initializers.第一个版本可能更容易阅读,并且可以更容易地识别初始化中的错误,这是指定初始化程序的优点之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM