bugprone-bitwise-pointer-cast¶
警告使用 std::bit_cast
或 memcpy
在指针之间进行转换的代码。
原因是 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
,以明确表达意图并启用来自编译器和代码分析器的警告,这些警告应得到相应的处理。