This conversion is guaranteed to work.
First, conversion from an object pointer to a void *
and back is described in section 6.3.2.3p1 of the C standard:
A pointer to void
may be converted to or from a pointer to any object type. A pointer to
any object type may be converted to a pointer to void
and back again; the result shall
compare equal to the original pointer
Second, conversion from a void *
to a intptr_t
and back is described in section 7.20.1.4p1:
The following type designates a signed integer type with the
property that any valid pointer to void
can be converted to
this type, then converted back to pointer to void
, and the
result will compare equal to the original pointer:
intptr_t
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 to void
, and the
result will compare equal to the original pointer:
uintptr_t
These types are optional.
In this case, an int *
(ip1
) is converted to a void *
(vp1
), and the void *
to a intptr_t
.
The intptr_t
is converted back to a void *
(vp2
). By 7.20.1.4p1, vp2
must compare equal to vp1
.
Then vp2
is converted to an int *
(ip2
). Since vp2
is the same as vp1
, the conversion of vp2
to int *
is equivalent to converting the vp1
to int *
and therefore will result in a pointer that will compare equal to ip1
as per 6.3.2.3p1.
a
points to one past the last element of an array object andb
points to the start of an array object that follows it." will not necessarily be true, due to some compilers keeping track of pointer provenance. See #45967262 – Socialminded