c++ - 为什么这种类型的双关语不是未定义的行为?
问题描述
这是一个我认为会调用未定义行为的玩具示例:
#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 没有警告。为什么不?
解决方案
为什么这种类型的双关语不是未定义的行为?
你的前提是错误的。行为未定义。
编译器没有警告......为什么不呢?
不需要编译器就 UB 发出警告。有时它会在星星对齐时确实如此,但通常编译器证明 UB 存在的成本高得令人望而却步。事实上,如果有可能,那么语言规则可能会指定程序为非良构程序。
或 UB 消毒剂。为什么不?
UB 消毒剂并不完美。它无法检测到所有 UB。考虑提交功能请求以实现对这种情况的检测 - 假设尚未提出请求。
推荐阅读
- python - 有没有更好的方法来编写这个 pyspark 拆分代码?
- mysql - 在 information_schema DB 中区分:默认为 NULL 的列与没有默认值的列
- javascript - 返回响应和访问成员时出现打字稿错误
- javascript - 按下 HTML 按钮时如何显示从 PHP 函数返回的数据
- c# - 如何切换阻止鼠标或键盘输入
- python - 如何在 Python 的 CSV 文件中保留引号?
- c# - 使用连接重新定义已定义的字符串
- java - 非法反射访问,试图发送电子邮件
- python - 如何定期拆分 Python 列表中的值?
- python - 使用新命令刷新 Tkinter 中的按钮