質問

私はそう__packedは非常に重要である(それはCPUのためです)各ビットが正確でなければならないいくつかのソフトウェアを書いています。

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;
} __packed;
}__packed page_union_t;

それは私の構造と労働組合です。しかし動作しません。

page_union_t p; //.....
//This:
p.frame=trg_page;
p.user=user;
p.rw=rw;
p.present=present;
//and this:
p.raw=trg_page<<12 | user<<2 | rw<<1 | present;

同じUINT32を作成する必要があります。しかし、彼らは同じものを作成しないでください。

私はそれが私の労働組合と間違っている見ることができない何かがありますか?

役に立ちましたか?

解決

あなたの構造体のみ31ビットを持っている。

他のヒント

私の知る限り、構造体のビットが格納される順序は、(すぎるとC89標準)C99規格で定義されていません。ほとんどの場合、ビットは、あなたが期待したものと逆の順序である。

あなたは、あなたが得た結果だけでなく、あなたが期待される結果を示している必要があります - それは診断で私たちを助けます。あなたが実行し、使用するコンパイラやプラットフォームにも大きな可能性があります。

<時間>

の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を有している..

ビット事項の正確な位置ならば、あなたの最も安全な賭けは、明示的な梱包で、unsigned char型の配列に構造の開梱。それ以外は、あまりにも実装に依存します。

これを見つけるかもしれない人には参考のため、packed属性を試してみます:

struct __attribute__((packed)){

}

あなたは、あなたが最初のケースに残さごみビットで終わるされていないことを確認している、あなたが事前に構造体のビットをクリアしていることを言及していない?

// maybe try this
page_union_t p = {0};
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top