There are some things that I do not understand about reinterpret_cast
.
The following snippet from cppreference has this to say about casting between integral values and pointers.
- A value of any integral or enumeration type can be converted to a pointer type. A pointer converted to an integer of sufficient size and back to the same pointer type is guaranteed to have its original value, otherwise the resulting pointer cannot be dereferenced safely (the round-trip conversion in the opposite direction is not guaranteed; the same pointer may have multiple integer representations) The null pointer constant NULL or integer zero is not guaranteed to yield the null pointer value of the target type; static_cast or implicit conversion should be used for this purpose.
In particular, from what I understand about the part about the "round-trip conversion in the opposite direction", C++ doesn't guarantee anything about a cast like
uintptr_t x;
reinterpret_cast<uintptr_t>(reinterpret_cast<void *>(x)) // == x ?
If there is such a guarantee, it would be good to see the corresponding reference.
My second question regards the correctness of the following:
Suppose int x; int y;
and x == y
is true, and that sizeof(int)
is strictly smaller than sizeof(void *)
. Then is it guaranteed that reinterpret_cast<void *>(x) == reinterpret_cast<void *>(y)
is true?
Intuitively, suppose in the physical memory x
has some garbage bytes after it, and y
also has some garbage bytes after it. Then by testing reinterpret_cast<void *>(x) == reinterpret_cast<void *>(y)
we are doing the following numerical comparison:
x garbage_x
==
y garbage_y
To clarify, the x refers to the portion of memory with value x in the expression reinterpret_cast<void *>(x)
and garbage_x
refers to the remaining portion of memory.
As another special case, what is the behavior of this with literals, say reinterpret_cast<void *>(1) == reinterpret_cast<void *>(1)
?
x
, not a pointer to it, so garbage neighbours should have no effect. – ExtraordinaryPTHREAD_CANCELED
which is defined as((void *)-1)
. In this case, it isn't even my choice to return an int directly, thepthread.h
header file defines this. – Calixx
, not the memory location&x
. In other words, firstint& x
is dereferenced, the value stored in a copy somewhere and then passed to the cast expression. Of course the copy might be elided or whatever but the garbage afterx
does not matter. – Extraordinary((void *)x)
)? – Calixuint8_t x=1; (void*)x
really only reinterprets1
, not some additional garbage. That would break a lot of things I believe. – Extraordinary