Section 7.18.1.4 of the C99 standard states:
The following type designates an unsigned integer type with the property that any valid pointer to
void
can be converted to this type, then converted back to pointer tovoid
, and the result will compare equal to the original pointer:
uintptr_t
Does this mean that only void *
types can be converted to uintptr_t
and back without changing the value of the original pointer?
In particular, I would like to know if the following code is required to use uintptr_t
:
int foo = 42;
void * bar = &foo;
uintptr_t baz = bar;
void * qux = baz;
int quux = *(int *)qux; /* quux == foo == 42 */
Or if this simpler version is guaranteed by the C99 standard to result in the same effect:
int foo = 42;
uintptr_t bar = &foo;
int baz = *(int *)bar; /* baz == foo == 42 */
Is a conversion to void *
required before converting a pointer to uintptr_t
and vice versa?
Best Answer
The distinction exists also because while any pointer to an object can be converted to
void *
, C doesn't require that function pointers can be converted tovoid *
and back again!As for pointers to objects of other types, the C standard says that any pointer can be converted to an integer, and an integer can be converted to any pointer, but such results are implementation-defined. Since the standard says that only
void *
is convertible back and forth, the safest bet is to cast the pointer tovoid *
first, as it might be that pointers that have different representations when converted touintptr_t
will result in a different integer representation too, so it could be conceivable that: