Suppose there are 2 structures defined ad such:
typedef struct {
T x;
T y;
} A;
typedef struct {
A a;
T z;
} B;
Can I treat a pointer to structure B as pointer to structure A?
In practice is this reliable/standard/portable/compiler-invariant:
B b = {{1,2},3};
A * a = &b;
print(a->x);
print(a->y);
C17 6.7.2.1 states this (emphasis mine):
Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa.
This means that you must "suitably convert" the pointer for the B b object into the type of it's first member. This conversion doesn't happen implicitly, you must do this by means of an explicit cast:
A * a = (A*)&b;
Doing so is well-defined and safe, as per the quoted part above.
Similarly, the compiler is not allowed to assume that a pointer to A and a pointer to B don't alias. The rule of effective type 6.5.7 ("strict aliasing") gives an exception for this case:
An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
...
- an aggregate or union type that includes one of the aforementioned types among its members
For example, during optimization a compiler calling the function void func (B* b) is not allowed to assume that a external linage variable extern A a; defined in some other translation unit was not changed by the function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With