关于C struct / union的可移植性问题
发布时间:2020-12-16 10:15:57 所属栏目:百科 来源:网络整理
导读:假设我从外部库中获得以下类型: union foreign_t { struct { enum enum_t an_enum; int an_int; } header; struct { double x,y; } point;}; 假设以下代码片段在不同平台和不同编译器上按预期工作是否安全? struct pair_t { double x,y;};union foreign_t
假设我从外部库中获得以下类型:
union foreign_t { struct { enum enum_t an_enum; int an_int; } header; struct { double x,y; } point; }; 假设以下代码片段在不同平台和不同编译器上按预期工作是否安全? struct pair_t { double x,y; }; union foreign_t foreign; struct pair_t *p_pair; p_pair = (struct pair_t *) &foreign; p_pair->x = 1234; p_pair->y = 4321; /* Expected result: (1234,4321) or something like that */ printf("(%lf,%lf)",foreign.point.x,foreign.point.y); 编辑: 按照严格的别名建议,我做了以下测试: #include <stdint.h> #include <stdio.h> int main() { uint16_t word = 0xabcd; uint8_t tmp; struct { uint8_t low; uint8_t high; } *byte = (void *) &word; tmp = byte->low; byte->low = byte->high; byte->high = tmp; printf("%xn",word); return 0; } 以上显然是无辜的代码是不可靠的: $gcc -O3 -fno-strict-aliasing -otest test.c $./test cdab $gcc -O3 -fstrict-aliasing -otest test.c $./test abcd 开发商没有和平…… 解决方法
正如您所写,我相信它应该适用于任何架构上的几乎任何编译器.但是,我确实认为它在技术上违反了
strict aliasing规则.您在不相关的指针类型之间进行转换,因此过于激进的优化器可能会重新排序某些内存读取和写入,因为它假定某些指针不会相互别名.
不幸的是,我认为有一种方法可以使这个代码绝对防止严格别名,假设你不能修改foreign_t的定义.由于内部结构没有名称,因此无法构造指向编译器将假定为可别的指针.但实际上,我认为您的代码不会出现问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |