bugprone-bitwise-pointer-cast

警告使用 std::bit_castmemcpy 在指针之间进行转换的代码。

原因是 std::bit_cast 在现代 C++ 中被宣传为通过 reinterpret_cast 进行类型穿透的安全替代方法。但是,不应该盲目地将 reinterpret_cast 替换为 std::bit_cast,如下所示:

int x{};
-float y = *reinterpret_cast<float*>(&x);
+float y = *std::bit_cast<float*>(&x);

这种直接替换的行为与 reinterpret_cast 完全相同,并且仍然会触发未定义行为。 std::bit_cast 是将输入指针的字节复制到不同类型的输出指针中,而不是将指向的内容复制,这可能违反严格别名规则。但是,只看代码,它看起来是“安全的”,因为它使用了 std::bit_cast,而 std::bit_cast 被宣传为安全的。

安全类型穿透的解决方案是对值类型应用 std::bit_cast,而不是对指针类型应用。

int x{};
float y = std::bit_cast<float>(x);

这样,输入对象的字节会被复制到输出对象中,这更安全。需要注意的是,如果不存在与生成的数值表示相对应的 To 类型的数值,则仍然可能出现未定义行为。编译器可能会优化此复制操作,并生成与原始 reinterpret_cast 版本相同的汇编代码。

C++20 之前的代码可能通过 memcpy 来移植 std::bit_cast,或者直接调用 memcpy,这同样存在问题。此检查也会检测到这种情况。

int* x{};
float* y{};
std::memcpy(&y, &x, sizeof(x));

或者,如果确实需要在指针之间进行转换,则应使用 reinterpret_cast,以明确表达意图并启用来自编译器和代码分析器的警告,这些警告应得到相应的处理。