防止 GCC 对结构联合中的位域重新排序
Prevent GCC from reordering bitfields in unions of structs
有一段代码如下:
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
的值将根据平台而变化,甚至可能是编译二进制文件的大小。
有没有办法告诉编译器"do not re-order this fields"?
将 MyUnion
类型的变量声明为 volatile
会实现这一点吗?
如果 union
是 packed
和 aligned(4)
, 如果您 100% 确定,是否可以确保位域不会被重新排序您将始终使用具有相同字节序的 32 位平台?
编辑
是否可以只针对一个特定的编译器完成上述操作?也就是说,如果不需要在不同的编译器之间兼容。
我认为评论中已经给出了总体"No"答案。通过这个回答,我想解决您关于 volatile
:
的问题
Would declaring MyUnion
as volatile
achieve this?
volatile
关键字不会改变您在此处寻找的任何行为。此外,您不能将联合声明为 volatile
。它是一个关键字,是变量声明的限定符。它告诉编译器变量值可以随时更改,因此应该始终重新加载该值(就像从内存中重新读取一样),而不是根据编译器看到的先前语句假设该值。
这用于当变量值可能因外部因素而改变时,例如当声明链接到实际物理值(例如微控制器中的寄存器)的变量时。
有一段代码如下:
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
的值将根据平台而变化,甚至可能是编译二进制文件的大小。
有没有办法告诉编译器"do not re-order this fields"?
将 MyUnion
类型的变量声明为 volatile
会实现这一点吗?
如果 union
是 packed
和 aligned(4)
, 如果您 100% 确定,是否可以确保位域不会被重新排序您将始终使用具有相同字节序的 32 位平台?
编辑
是否可以只针对一个特定的编译器完成上述操作?也就是说,如果不需要在不同的编译器之间兼容。
我认为评论中已经给出了总体"No"答案。通过这个回答,我想解决您关于 volatile
:
Would declaring
MyUnion
asvolatile
achieve this?
volatile
关键字不会改变您在此处寻找的任何行为。此外,您不能将联合声明为 volatile
。它是一个关键字,是变量声明的限定符。它告诉编译器变量值可以随时更改,因此应该始终重新加载该值(就像从内存中重新读取一样),而不是根据编译器看到的先前语句假设该值。
这用于当变量值可能因外部因素而改变时,例如当声明链接到实际物理值(例如微控制器中的寄存器)的变量时。