bugprone-bitwise-pointer-cast¶
Warns about code that tries to cast between pointers by means of
std::bit_cast
or memcpy
.
The motivation is that std::bit_cast
is advertised as the safe alternative
to type punning via reinterpret_cast
in modern C++. However, one should not
blindly replace reinterpret_cast
with std::bit_cast
, as follows:
int x{};
-float y = *reinterpret_cast<float*>(&x);
+float y = *std::bit_cast<float*>(&x);
The drop-in replacement behaves exactly the same as reinterpret_cast
, and
Undefined Behavior is still invoked. std::bit_cast
is copying the bytes of
the input pointer, not the pointee, into an output pointer of a different type,
which may violate the strict aliasing rules. However, simply looking at the
code, it looks “safe”, because it uses std::bit_cast
which is advertised as
safe.
The solution to safe type punning is to apply std::bit_cast
on value types,
not on pointer types:
int x{};
float y = std::bit_cast<float>(x);
This way, the bytes of the input object are copied into the output object, which
is much safer. Do note that Undefined Behavior can still occur, if there is no
value of type To
corresponding to the value representation produced.
Compilers may be able to optimize this copy and generate identical assembly to
the original reinterpret_cast
version.
Code before C++20 may backport std::bit_cast
by means of memcpy
, or
simply call memcpy
directly, which is equally problematic. This is also
detected by this check:
int* x{};
float* y{};
std::memcpy(&y, &x, sizeof(x));
Alternatively, if a cast between pointers is truly wanted, reinterpret_cast
should be used, to clearly convey the intent and enable warnings from compilers
and linters, which should be addressed accordingly.