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.