I want to stick the bits of an int32_t
into the type uint32_t
without any transformation, just a reinterpretation. The following code does precisely what I want:
int32_t iA = -1;
uint32_t uA = *(uint32_t*)&iA;
But I was wondering, can I rely on the following easier to write cast generating the same (or less) assembly, ideally just mov
s? (i.e., it'll never do "math" to it, leaving the underlying bits untouched.)
int32_t iB = -1;
uint32_t uB = (uint32_t)iB;
assert(uA == uB); // ?
Until C++20, the representation of signed integers is implementation-defined. However, std::intX_t
are guaranteed to have 2s'-complement representation even before C++20:
int8_t
,int16_t
,int32_t
,int64_t
- signed integer type with width of exactly 8, 16, 32 and 64 bits respectively with no padding bits and using 2's complement for negative values (provided only if the implementation directly supports the type)
When you write
std::int32_t iA = -1;
std::uint32_t uA = *(std::uint32_t*)&iA;
you get the value with all bits set. The standard says that accessing std::int32_t
through a pointer of type std::uint32_t*
is permitted if "type is similar to ... a type that is the signed or unsigned type corresponding to the dynamic type of the object". Thus, strictly speaking, we have to ensure that std::uint32_t
is indeed an unsigned type corresponding to std::int32_t
before dereferencing the pointer:
static_assert(std::is_same_v<std::make_unsigned_t<std::int32_t>, std::uint32_t>);
When you write
std::int32_t iB = -1;
std::uint32_t uB = (std::uint32_t)iB;
you rely on the conversion into the unsigned type that is well-defined and is guaranteed to produce the same value.
As for the assembly, both casts are no-ops:
std::uint32_t foo() {
std::int32_t iA = -1;
static_assert(std::is_same_v<std::make_unsigned_t<std::int32_t>, std::uint32_t>);
return *(std::uint32_t*)&iA;
}
std::uint32_t bar() {
std::int32_t iB = -1;
return (std::uint32_t)iB;
}
result in:
foo():
mov eax, -1
ret
bar():
mov eax, -1
ret
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