Does reinterpret_casting an integral to a pointer type and back yield the same value?
Asked Answered
T

2

6

According to http://en.cppreference.com/w/cpp/language/reinterpret_cast, it is known that reinterpret_cast a pointer to an integral of sufficient size and back yield the same value. I'm wondering whether the converse is also true by the standards. That is, does reinterpret_cast an integral to a pointer type of sufficient size and back yield the same value?

Theory answered 11/3, 2015 at 5:21 Comment(5)
No, this is not guaranteed. For example, different integers may convert to the same address.Hooten
@n.m. Could you give a concrete example? Note that reinterpret_cast is used here to perform the conversion.Theory
Take the 8086 architecture. The integer 0x10002000L when interpreted as 0x1000:0x2000 (segment and offset) corresponds to the physical address 0x12000. So does the integer 0x12000000L. Nothing prevents the compiler from converting 0x10002000L to 0x1200:0x0000 segment and offset, then convert it back to 0x12000000L. In the bad old days this was known as huge pointer normalization.Hooten
In addition, on some systems (8051 architecture), the memory space is so small that there are no pointer types that are big enough to hold a uint32_t for example. The 8051 supports 4 pointer types: 1 byte (idata), 1 byte (pdata), 2 byte (xdata) and 3 byte (general pointer).Seduce
No, integer-to-pointer-back-to-integer conversion is not guaranteed. Quote from cppreference: "...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)...".Unrealizable
I
3

No, that is not guaranteed by the standard. Quoting all parts of C++14 (n4140) [expr.reinterpret.cast] which concern pointer–integer conversions, emphasis mine:

4 A pointer can be explicitly converted to any integral type large enough to hold it. The mapping function is implementation-defined. [ Note: It is intended to be unsurprising to those who know the addressing structure of the underlying machine. —end note ] ...

5 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 3.7.4.3, the result of such a conversion will not be a safely-derived pointer value. —end note ]

So starting with an integral value and converting it to a pointer and back (assuming no size issues) is implementation-defined. Which means you must consult your compiler's documentation to learn whether such a round trip preserves values or not. As such, it is certainly not portable.

Ideally answered 27/4, 2015 at 10:32 Comment(0)
S
0

I get exactly this problem in library exporting pointers to objects as opaque identifiers and now attempting to recover these pointers from external calls don't work for old x86 CPU's (in the time of windows 98). So, while we can expect that behaviour, this is false in general case. In 386-CPU the address is composed by overlapped pointers so the address of any memory position is not unique, and I found that conversion back don't recover original value.

Shoshana answered 6/4, 2015 at 17:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.