c++ - 防止 GCC 对结构 union 中的位域重新排序

标签 c++ c gcc compiler-optimization bit-fields

有一段代码如下:

typedef union
{
    struct bits
    {
        uint32_t bit0 : 1;
        uint32_t bit1 : 1;
        uint32_t bit2 : 1;
        ...
        ...
        uint32_t bit14 : 1;
    }

    uint32_t value;

} MyUnion;

重要的是要防止编译器对位域重新排序,否则 value 的值将根据平台发生变化,甚至可能根据编译后的二进制文件的大小发生变化。

有没有办法告诉编译器“不要重新排序这些字段”?

MyUnion 类型的变量声明为 volatile 会实现这一点吗?

如果 unionpackedaligned(4)是否有可能确保位域不会被重新排序,如果您 100% 确定您将始终使用 32 位平台,并具有相同的字节顺序?

编辑

是否可以只针对一个特定的编译器完成上述操作?也就是说,如果不需要跨不同的编译器兼容。

最佳答案

我认为评论中已经给出了总体“否”的答案。通过这个答案,我想解决您关于 volatile 的问题:

Would declaring MyUnion as volatile achieve this?

volatile 关键字不会改变您在此处寻找的任何行为。此外,您不能将 union 声明为 volatile。它是一个关键字,是变量声明的限定符。它告诉编译器变量值可以随时更改,因此应该始终重新加载该值(就像从内存中重新读取一样),而不是根据编译器看到的先前语句假设该值。 这用于当变量值可能因外部因素而改变时,例如当声明链接到实际物理值(例如微 Controller 中的寄存器)的变量时。

关于c++ - 防止 GCC 对结构 union 中的位域重新排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57392896/

相关文章:

c - 使用指令 #define 定义指针 : need help to understand this piece of code

目标名称的 Xcode/GCC 预定义宏?

c++ - 为什么 gcc 不将类声明编译为引用参数?

c++ - 非阻塞 Connect() 上的 WSAEWOULDBLOCK 错误

c++ - Qt 所见即所得 - 字体大小问题

c# - 嵌入式 C 中的 Modbus RTU 实现

c - STM32 - FreeRTOS xQueue 接收不完整的数组

c++ - 在数组中查找重复项

C++ 非抽象析构函数继承

c - C 中的 strcat() 函数更改了程序中的随机变量?