c - C 结构/union 的可移植性问题

标签 c struct portability unions

假设我有来自外部库的以下类型:

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("%x\n", 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 的定义,我不认为有什么方法可以使这段代码绝对防止严格的别名。由于内部结构没有名称,因此您无法构造指向它的指针,编译器将假定它是可别名的。不过在实践中,我认为您的代码不会出现问题。

关于c - C 结构/union 的可移植性问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1575355/

相关文章:

c - 保存不均匀动态矩阵的结构?

c - 索拉里斯 10 : handle gracefully ENOBUFS error when changing socket buffer

c++ - C++ 中的可移植高精度双时间戳?

c - 在C中修改文本文件的内容

c - 实用分段核心转储

swift - Apple 对多线程引用和值类型的描述

c - 双向链表: Incompatible pointer types

portability - 使用不可移植代码的理由

c - 返回函数本身作为返回值

c++ - HTC Smart 中的主页按钮事件是否传送到我自己的应用程序?