加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

关于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的定义.由于内部结构没有名称,因此无法构造指向编译器将假定为可别的指针.但实际上,我认为您的代码不会出现问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读