In this article the following is mentioned regarding reinterpret_cast
of integers and pointers:
(the round-trip conversion in the opposite direction is not guaranteed; the same pointer may have multiple integer representations)
Do I understand correctly that the following is then not guaranteed by the standard:
intptr_t x = 5;
void* y = reinterpret_cast<void*>(x);
assert(x == reinterpret_cast<intptr_t>(y));
Can someone confirm?
Your interpretation is correct. The relevant paragraph of the standard is [expr.reinterpret.cast]/5 in C++17:
A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined. [ Note: Except as described in 6.7.4.3, the result of such a conversion will not be a safely-derived pointer value. — end note ]
Thus, while the mapping from pointers to integers is guaranteed to have a left inverse (and therefore be injective), no guarantee is made that it is bijective; whether or not it is part of the "implementation-defined" behaviour. As cppreference points out, there may be several integers that convert to the same pointer.