问题
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