为什么这种类型的惩罚不是未定义的行为?

c--*_*c-- 1 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;
}
Run Code Online (Sandbox Code Playgroud)

我很确定取消引用它的结果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
Run Code Online (Sandbox Code Playgroud)

没有来自编译器或UB消毒剂的警告.为什么不?

eer*_*ika 6

为什么这种类型的惩罚不是未定义的行为?

你的前提是错的.该行为不确定的.

编译器没有警告......为什么不呢?

编译器不需要警告UB.有时确实如此,当星星对齐时,但编译器证明UB的存在通常是非常昂贵的.事实上,如果这可能的,那么语言规则很可能会指定要代替病态的程序.

或UB消毒剂.为什么不?

UB消毒剂并不完美.它无法检测到所有UB.考虑提交实现此案例检测的功能请求 - 假设尚未请求.


Vit*_*meo 5

没有来自编译器或UB消毒剂的警告.为什么不?

这并不意味着您没有未定义的行为.编译器和清理程序可以尽力检测它,但不能保证每次都能捕获它.

您可以确定的唯一方法是阅读标准并检查您的使用是否reinterpret_cast定义明确.