c++ - 为什么这种类型的双关语不是未定义的行为?

标签 c++ undefined-behavior type-punning

这是一个玩具示例,我认为它会调用未定义的行为:

#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/

相关文章:

c++ - 如何判断我平台上的punning类型是否可以?

c - 纯 C 多态性、类型双关和严格的别名。这有多合法?

c++ - 快速读取文件

java - 变量的地址在执行过程中可以改变吗?

c++ - 如何在c++代码中生成生成粒子的总动能和总势能?

c - 关于常用算术转换的问题-GCC编译器

c++ - 为什么 "boost.thread"手动调用 "intrusive_ptr_add_ref"?

c - 内存访问冲突不会在 c 中给出任何错误

c++ - 表达式的行为 : Defined or Undefined?

c++ - `volatile` 是否允许使用 union 进行类型双关?