Aggregate initialization, set member pointer to same struct member

风流意气都作罢 提交于 2020-05-26 14:38:27

问题


Is it possible to use aggregate initialization to make a pointer aptr point to a which is a member of the same 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++.


回答1:


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

C++2a GNU

Regarding the correctness of the initialization:

For 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++:

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.

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 s.a, just its address which is accessible at this point.

So this is a correct initialization both for C and C++.


Something to note with this code, in MSVC, there is a compilation error:

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

Using std:c++latest the error changes to:

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

However, compilers as old as clang 3.1 and C++03 GNU compile fine with no warnings.

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, designated initializers are explicitly shown.



来源:https://stackoverflow.com/questions/60190650/aggregate-initialization-set-member-pointer-to-same-struct-member

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!