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
ビットフィールド構造には31ビットしか定義されていないため、最下位ビットが使用されないため、最初の結果の最後の16進数はEになります。