Can I use type punning with union members which are pointer to signed and unsigned versions of a type? For example, is the following usage of p.u
guaranteed to work by the standard?
void foo(unsigned *u);
int num = 7;
union
{
int *i;
unsigned *u;
} p;
p.i = #
foo(p.u);
Assuming that num
is non-negative it seems it should be fine on most platforms. I'm wondering whether it's guaranteed that the two pointers will have the same representation in memory?
There are very strictly speaking no guarantees that these two pointer types have the same representation in memory. The C standard only guarantees that (6.3.2.3) "A pointer to an object type may be converted to a pointer to a different object type." /--/ "Otherwise, when converted back again, the result shall compare equal to the original pointer."
To satisfy this requirement in practice, it is however extremely likely that int*
and unsigned*
have the same representation in memory. To the point where I wouldn't worry about it.
The type punning itself is otherwise well-defined (6.2.6), as is accessing an object of effective type int
through an unsigned int*
, or an object of effective type unsigned int
through a int*
(6.5/7 "strict aliasing").
The real question here is why you'd use such a union instead of always accessing the memory by an unsigned int*
and then cast the de-referenced value to int
when needed.