这是一个玩具示例,我认为它会调用未定义的行为:
#include <cstdint>
#include <iostream>
#include <vector>
int
main()
{
std::vector<uint16_t> foo = {0, 0x42F6};
std::cout << *reinterpret_cast<float*>(foo.data()) << std::endl;
return 0;
}
我很确定取消引用 reinterpret_cast
的结果会违反严格的别名规则。然而:
$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
$ g++ -fstrict-aliasing -Wstrict-aliasing -fsanitize=undefined -std=c++14 -o a a.cpp
$ ./a
123
没有来自编译器或 UB sanitizer 的警告。为什么不呢?
最佳答案
Why is this type punning not undefined behavior?
你的前提是错误的。行为是未定义的。
No warnings from the compiler ... Why not?
编译器不需要警告 UB。 有时确实如此,当星星对齐时,但编译器证明 UB 存在的成本通常高得令人望而却步。事实上,如果它是可能的话,那么语言规则可能会将程序指定为病式。
or the UB sanitizer. Why not?
UB sanitizer 并不完美。它无法检测到所有 UB。考虑提交功能请求以实现对这种情况的检测 - 假设尚未请求。
关于c++ - 为什么这种类型的双关语不是未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51670922/