Am I allowed to use a variable being initialized inside a designated initializer?
Consider the following listing:
struct A {
int a;
int * const a_ptr;
};
struct A foo(int a) {
struct A result = {
.a = a,
.a_ptr = &result.a
};
return result;
}
Am I allowed to use result
in this designated initializer expression? Is this behavior defined? Is this code portable?
Update
My bad, the example contains a potential stack corruption. The listing should be:
struct A {
int a;
int * const a_ptr;
};
void foo(int a) {
struct A result = {
.a = a,
.a_ptr = &result.a
};
bar(&result);
}
CodePudding user response:
The initialization by itself is fine.
At the time result
is declared, its address (as well as the addresses of its fields) is constant. So it is safe to use &result.a
in the initializer of result
.
What is a problem however is that you're returning a copy of this structure. This copy contains the address of a local variable that no longer exists, so attempting to use the value of the a_ptr
member of the returned struct will trigger undefined behavior.
CodePudding user response:
The question has changed completely, here is my new answer:
Your code is fine, you can check this, it won't assert on any platform.
You pass the pointer to the local variable result
to bar
. In bar
that local variable still exists p
points to that variable (result). Therefore the a_ptr
still points to result.a
.
But I'm just wondering what you're trying to achieve here.
#include <assert.h>
struct A {
int a;
int* const a_ptr;
};
void bar(struct A *p)
{
assert(p->a_ptr == &p->a);
}
void foo(int a) {
struct A result = {
.a = a,
.a_ptr = &result.a
};
bar(&result);
}
int main()
{
foo(2);
}
BTW:
struct A result = {
.a = a,
.a_ptr = &result.a
};
is equivalent to this:
struct A result;
result.a = a;
result.a_ptr = &result.a;
but for latter you'd need to declare int* a_ptr;
instead of int* const a_ptr;
.