From the C++ standard:
5.2.10.3
The mapping performed by reinterpret_cast might, or might not, produce a representation different from the original value.
I've been trained at this very site to believe and repeat this. (Even if it's possibly just trivia). A reinterpret_cast
from float*
to int*
is allowed to produce a different bit pattern. The only guarantee is that reinterpret_cast
-ing that result back to float*
will produce the original bit pattern.
My question: Does this ever happen? Is there an existing, real-world platform or CPU or compiler that actually reinterpret_cast
s to a different bit pattern? If not, are there any real-world situations where reinterpret_cast
has any runtime overhead?
In all my experience with reinterpret_cast
, the cast was a directive to the compiler, not the runtime.
Pointers can in principle be different sizes. The largest pointer, if there is any difference (disregarding member pointers, talking about real pointers), is char*
, since a char
by definition is a byte and can be anywhere, no alignment. void*
must be able to represent char*
.
On a system with int*
using fewer bits than char*
, reinterpret-casting in that direction might be a bit risky.
I think with these pointers (heh) you can find this in the standard. It's the requirement about void*
being large enough for any pointer, and the thing about alignment: the stricter/larger, the fewer bits needed for pointer to that type. But I have not ever heard of any extant system where there is such difference.
Standardese regarding void*
being able to represent char*
:
C++11 §3.9.2/4:
”
A pointer to cv-qualified (3.9.3) or cv-unqualifiedvoid
can be used to point to objects of unknown type. Such a pointer shall be able to hold any object pointer. An object of type cvvoid*
shall have the same representation and alignment requirements as cvchar*
The “any object pointer” implies vaguely that there are different sizes of pointer.
Standaredese regarding the alignment of referent:
C++11 §5.2.10/7:
”
An object pointer can be explicitly converted to an object pointer of a different type. When a prvaluev
of type “pointer toT1
” is converted to the type “pointer to cvT2
”, the resultis static_cast<
cvT2*>(static_cast<
cvvoid*>(v))
if bothT1
andT2
are standard-layout types (3.9) and the alignment requirements ofT2
are no stricter than those ofT1
, or if either type isvoid
. Converting a prvalue of type “pointer toT1
” to the type “pointer toT2
” (whereT1
andT2
are object types and where the alignment requirements ofT2
are no stricter than those ofT1
) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified.
It’s worth noting that later on in the standard there is some support for C-style emulation of class derivation, that apparently contradicts the “any other” at the end above:
C++11 §9.2/20,
”
A pointer to a standard-layout struct object, suitably converted using areinterpret_cast
, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa.
In this case the two objects necessarily have the same alignment, while the previous cited paragraph talked only about alignment of types – but clearly the formal little contradiction is not a practical problem, as I see it.
I've worked on platforms where char*
was larger than int*
,
and on platforms where they had a different layout, even though
the size was the same. Neither of the machines in question are
particularly relevant today, however (although the second, the
PDP-10, was one of the more important machines in its heyday).
It's also conceivable that some compilation modes on an Intel in
native mode (or what used to be called native mode) would
"normalize" pointers in a reinterpret_cast
, or even an
implicit conversion, in order to facilitate address comparisons.
It's also conceivable (although I've not seen it) that such
conversions enforce correct alignment, e.g. a conversion from
char*
to int*
might force the 2 low-order bits to 0. In
practice, however, I don't think, today, that you're likely to
see a reinterpret_cast
make any changes between data pointer
types. The issue is more historic. (But I'm not sure about
modern embedded processors. From what I understand, many of them
are word addressing, and so if sizeof(int) != sizeof(char)
, they're
likely to need a special format to address char
.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With