fededevi
fededevi

Reputation: 181

Struct Extension in C

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);

Upvotes: 4

Views: 318

Answers (1)

Lundin
Lundin

Reputation: 215350

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.

Upvotes: 6

Related Questions