当前位置:  开发笔记 > IOS > 正文

联合和结构包装问题

如何解决《联合和结构包装问题》经验,为你挑选了2个好方法。

我正在编写一些软件,其中每个位必须精确(它是CPU的),所以__packed非常重要.

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.但他们并没有创造同样的东西.

有什么我看不出我的工会有问题吗?



1> steve..:

你的结构只有31位



2> Jonathan Lef..:

AFAIK,结构中的位的存储顺序由C99标准(以及C89标准)定义.最有可能的是,这些位的顺序与您的预期相反.

您应该已经显示了您获得的结果以及您期望的结果 - 这将有助于我们进行诊断.您使用的编译器和您运行的平台也可能很重要.


在MacOS X 10.4.11(PowerPC G4)上,此代码:

#include 
#include 

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 
#include 

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位.

推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有