Ser*_*nov 5 c++ strict-aliasing undefined-behavior
我的一位同事正在研究与二进制数据阵列一起使用的C++代码.在某些地方,他的代码就像
char *bytes = ...
T *p = (T*) bytes;
T v = p[i]; // UB
Run Code Online (Sandbox Code Playgroud)
在这里,T
有时可以short
或int
(分别假设16位和32位).
现在,与我的同事不同,我属于"没有UB,如果可能的话"阵营,而他更像是"如果它有效,那就没关系".我正在努力试图说服他.
鉴于:
bytes
真的来自这个编译单元之外的某个地方,从一些二进制文件中读取.
可以安全地假设数组实际上包含本机字节序中的整数.
在实践中,鉴于MSVC 2017和gcc 4.8等主流C++编译器以及Intel x64硬件,这样的事情真的很安全吗?我知道它不会T
是,比如说,float
(过去曾被它咬过).
char*
可以在不破坏严格别名规则的情况下为其他实体设
只有在最初p + i
不是T
原始代码时,您的代码才是UB .
char* byte = (char*) floats;
int *p = (int*) bytes;
int v = p[i]; // UB
Run Code Online (Sandbox Code Playgroud)
但
char* byte = (char*) floats;
float *p = (float*) bytes;
float v = p[i]; // OK
Run Code Online (Sandbox Code Playgroud)
如果原点byte
是"未知",则编译器不能从UB中获益以进行优化,并且应该假设我们处于有效的情况并根据生成代码.但你如何保证它是未知的?即使在TU之外,像Link-Time Optimization这样的东西也许可以提供隐藏的信息.