Reputation: 2080
Disclaimer: The following is trying to simplify the problem as much as possible. Originally the variable int x
is a struct but I would figure that this is not important here.
Assume we have two structs in a union (I have no influence on this)
typedef struct a_t {
int x;
int irrelevant;
} a_;
typedef struct b_ {
float also_irrelevant;
int x;
} b_;
typedef union uni_t{
a_ a;
b_ b;
} uni;
Is it possible to access x
in both structures by the same statement like ptr_to_struct->x
? But afaik the pointer needs the correct type at compile time. So a dependend declaration similar to this Pseudocode
if (union contains a_)
{
a_ * ptr_to_struct; // but outside of this scope
ptr_to_struct = &(uni.a);
}
else
{
b_ * ptr_to_struct; // but outside of this scope
ptr_to_struct = &(uni.b);
}
is impossible as far as I know.
Are there possibilties to get a "general" access to the variable x
independent of the current state of the union?
Upvotes: 1
Views: 450
Reputation: 249462
It is impossible. C does not have reflection, so the "name" x is not available at runtime. Nor do you have any data within the structs that indicates which type a given instance is (i.e. it's not a "tagged union").
Upvotes: 1
Reputation: 726899
You are correct, it is not possible. The type of ptr_to_struct
is a secondary problem here. The primary problem is that the address of x
inside uni
changes based on which struct
is "active" inside the union
:
a_
is "active", the offset of x
from the top of the union
is zerob_
is "active", the offset of x
from the top of the union
is sizeof(float)
plus possible additional offset for field alignmentOne solution to this problem would be to put x
on the same spot in the initial sequence of fields in both struct
s:
typedef struct a_t {
int x;
int irrelevant;
} a_;
typedef struct b_t {
int x; // Moved to the top
float also_irrelevant;
} b_;
Now that x
occupies the same position, C makes a guarantee that the address of x
in the union is going to be the same if you access it through a.x
or through b.x
.
Upvotes: 1