【发布时间】:2019-08-07 11:01:00
【问题描述】:
有一段代码如下:
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 会实现此目的吗?
如果union 是packed 和aligned(4),如果您100% 确定您将始终使用32 位平台,是否可以确保位域不会被重新排序, 具有相同的字节顺序?
编辑
是否可以仅针对一种特定的编译器完成上述操作?也就是说,如果不需要跨不同编译器兼容的话。
【问题讨论】:
-
没有什么能阻止
value即使没有重新排序也能改变。 -
简短的回答是:不,没有。
-
是的,这是不可能的。但是,如果您总是使用具有相同字节顺序的 32 位平台,则位顺序不应该改变。我找到了一篇关于位域的好文章jkz.wtf/bit-field-packing-in-gcc-and-clang
-
如果您需要强制位的确切顺序和排列,位域不是适合这项工作的工具。你可以花时间修修补补,你可以尝试使用各种编译器扩展,但最终你仍然不确定并且没有保证,而且(在我看来)这将比它的价值更麻烦。相反,如果您需要强制位的确切顺序和排列,只需硬着头皮使用
unsigned int以及一些显式的屏蔽和移位技术。位域很诱人,但pyrite 也是如此。 -
@Dan 包含的
union对包含的struct中的位域顺序没有任何影响。位域在其底层存储单元中分配的方向(在您的情况下为uint32_t)是实现定义的。
标签: c++ c gcc compiler-optimization bit-fields