AFAIK,存储结构中位的顺序未由 C99 标准(以及 C89 标准)定义。最有可能的是,这些位的顺序与您的预期相反。
您应该已经展示了您得到的结果以及您预期的结果 - 这将有助于我们进行诊断。您使用的编译器和您运行的平台也可能很重要。
在 MacOS X 10.4.11 (PowerPC G4) 上,此代码:
#include <inttypes.h>
#include <stdio.h>
typedef union
{
uint32_t raw;
struct
{
unsigned int present:1;
unsigned int rw:1;
unsigned int user:1;
unsigned int dirty:1;
unsigned int free:7;
unsigned int frame:20;
};
} page_union_t;
int main(void)
{
page_union_t p = { .raw = 0 }; //.....
unsigned trg_page = 0xA5A5A;
unsigned user = 1;
unsigned rw = 1;
unsigned present = 1;
p.frame = trg_page;
p.user = user;
p.rw = rw;
p.present = present;
printf("p.raw = 0x%08X\n", p.raw);
p.raw = trg_page<<12 | user<<2 | rw<<1 | present;
printf("p.raw = 0x%08X\n", p.raw);
p.raw <<= 1;
printf("p.raw = 0x%08X\n", p.raw);
return(0);
}
产生显示的结果:
p.raw = 0xE014B4B4
p.raw = 0xA5A5A007
p.raw = 0x4B4B400E
颠倒字段的顺序,结果更接近于解释:
#include <inttypes.h>
#include <stdio.h>
typedef union
{
uint32_t raw;
struct
{
unsigned int frame:20;
unsigned int free:7;
unsigned int dirty:1;
unsigned int user:1;
unsigned int rw:1;
unsigned int present:1;
};
} page_union_t;
int main(void)
{
page_union_t p = { .raw = 0 }; //.....
unsigned trg_page = 0xA5A5A;
unsigned user = 1;
unsigned rw = 1;
unsigned present = 1;
p.frame = trg_page;
p.user = user;
p.rw = rw;
p.present = present;
printf("p.raw = 0x%08X\n", p.raw);
p.raw = trg_page<<12 | user<<2 | rw<<1 | present;
printf("p.raw = 0x%08X\n", p.raw);
p.raw <<= 1;
printf("p.raw = 0x%08X\n", p.raw);
return(0);
}
这给出了结果:
p.raw = 0xA5A5A00E
p.raw = 0xA5A5A007
p.raw = 0x4B4B400E
第一个结果将 E 作为最后一个十六进制数字,因为未使用最低有效位,因为位域结构仅定义了 31 位。