c – 什么时候类型惩罚指针在实践中是安全的?
作者:互联网
我的一位同事正在研究与二进制数据阵列一起使用的C代码.在某些地方,他的代码就像
char *bytes = ...
T *p = (T*) bytes;
T v = p[i]; // UB
这里,T有时可以是short或int(分别假设为16和32位).
现在,与我的同事不同,我属于“没有UB,如果可能的话”阵营,而他更像是“如果有效,那就没关系”.我正在努力试图说服他.
鉴于:
>字节真的来自这个编译单元之外的某个地方,从一些二进制文件中读取.
>可以安全地假设数组实际上包含本机字节序中的整数.
在实践中,鉴于MSVC 2017和gcc 4.8以及Intel x64硬件这样的主流C编译器,这样的事情真的很安全吗?我知道如果T是浮动(过去曾被它咬过),那就不行了.
解决方法:
char *可以在不破坏严格别名规则的情况下对其他实体进行别名.
只有当最初的p i不是T时,你的代码才是UB.
char* byte = (char*) floats;
int *p = (int*) bytes;
int v = p[i]; // UB
但
char* byte = (char*) floats;
float *p = (float*) bytes;
float v = p[i]; // OK
如果byte的起源是“未知”,则编译器不能从UB中获益以进行优化,并且应该假设我们处于有效的情况并根据生成代码.
但你如何保证它是未知的?即使在TU之外,像Link-Time Optimization这样的东西也许可以提供隐藏的信息.
标签:strict-aliasing,c,undefined-behavior 来源: https://codeday.me/bug/20190910/1800376.html