I have structure like below.
struct result{
int a;
int b;
int c;
int d;
}
and union like below.
union convert{
int arr[4];
struct result res;
}
and I type pun as below.
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1; // Here is my question, is it well defined?
printf("%d %d\n", pointer->res.a, pointer->res.b);
Most of the time, type punning won't cause any problems. It is considered undefined behavior by the C standard but will usually do the work you expect. That is unless you're trying to squeeze more performance out of your code through optimizations.
Type punning. A form of pointer aliasing where two pointers and refer to the same location in memory but represent that location as different types. The compiler will treat both "puns" as unrelated pointers. Type punning has the potential to cause dependency problems for any data accessed through both pointers.
pointer->res.a
is fine but the behaviour of pointer->res.b
is undefined.
There could be an arbitrary amount of padding between the a
and b
members.
Some compilers allow you to specify that there is no padding between members but of course then you are giving up portability.
Is this type punning well defined?
struct result{
int a,b,c,d;
}
union convert {
int arr[4];
struct result res;
}
int arr1[4] = {1,2,3,5};
union convert *pointer = (union convert *) arr1;
(union convert *) arr1
risks alignment failure.
A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. C11dr §6.3.2.3 8
There is no requirement that union convert
and int
share the same alignment. union convert
requirements may exceed int
for example.
Consider this possibility: arr1[]
lives on int
street where all addresses are multiple of 4. union
and struct
friends lives on "multiple of 8" street. arr1[]
might have address 0x1004 (not a multiple of 8).
In 2019, alignment failures are more commonly seen with char
(needing 1) and other types needing 2 or more. In OP's select case, I doubt a real platform will have alignment issues, yet incorrect alignment remains possible.
This type punning is not well defined.
Additional concerns
Other answers and comments discuss padding issues, which further identifies trouble.
@Eric Postpischil comment about improper access with pointer->res.a
adds more reasons to consider this UB.
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