是否可以将一种类型的位域转换为具有相同总位数的另一种类型的位域?

时间:2016-06-27 16:28:20

标签: c struct bit-fields c89

任何人都可以判断是否可以将一种类型的位域分配给其他类型?支持C90编译器。

这是位域的结构:

typedef struct{
    unsigned int ERA:2;
    unsigned int destar:2;
    unsigned int srcar:2;
    unsigned int opcode:4;
    unsigned int grp:2;
    unsigned int dumy:3;
} Command;
typedef struct{
    unsigned int cell:15;
} Word;

这是主程序:

int main(int argc, const char * argv[]){
    Word word;
    Command cmd;
    cmd.grp = 2;
    word = cmd;
}

假设我在这里有这15位:

我们按此顺序排列:

命令:

Dumy |    grp | opcode |   srcar | destar | ERA
 0 0 0   0 1    0 0 0 1     10      0 0     0 0

词语:

 |          word              |
000000000000000

目标是单词将等于整个Command(word = command)所以我们会看起来像这样:

|           word            |
000010001100000

3 个答案:

答案 0 :(得分:3)

你可能想要的是一个联盟:

typedef union {
    struct {
        //unsigned int:1;        // padding bit either here...
        unsigned int ERA:2;
        unsigned int destar:2;
        unsigned int srcar:2;
        unsigned int opcode:4;
        unsigned int grp:2;
        unsigned int dumy:3;
        //unsigned int:1;         // ...or here, depending on how you want to read it
    } cmd;
    uint16_t word;
} Cmd;

int main(int argc, const char * argv[]){
    Cmd cmd;
    cmd.cmd.grp = 2;
    printf("word=%u\n", cmd.word);
}

答案 1 :(得分:1)

由于位域布局取决于编译器,我不确定您的期望是什么 以下代码段可能包含未定义的行为,但我想这就是您要找的内容。

Word word;
Command cmd;
cmd.grp = 2;

union
{
    Word word;
    Command cmd;
} u;

u.cmd = cmd;
word = u.word;

答案 2 :(得分:0)

如果编译器从第0位分配位字段,那么" word"和" cmd"将占据位0:14。

如果编译器从第15位(或者第31位,这是DSP处理器的大多数编译器中的一般情况)分配位字段,那么"字"和" cmd"将占用比特15:1(或32比特字的情况下为31:17)。

所以似乎可以避免添加另一个位来完成比特字段结构到编译器分配的字大小。

但这样做是个好习惯。

如果" word"编译器是一个字节。有微控制器,他们的单词是一个字节。在这种情况下,联合定义可能会导致错误。

typedef union {
    struct {
        unsigned int ERA:2;
        unsigned int destar:2;
        unsigned int srcar:2;
        unsigned int opcode:4; // When the compiler see that the opcode
                               // bit field is to big to be allocated in the
                               // first byte, The compiler might allocate 
                               // opcode at the first allocation in the
                               // second byte that is allocated to this 
                               // union.
        unsigned int grp:2;
        unsigned int dumy:3;
    } cmd;
    uint16_t word;
} Cmd; 

在这种情况下,联盟应该以这种方式写出

typedef union {
    struct {
        unsigned int ERA:2;
        unsigned int destar:2;
        unsigned int srcar:2;
        unsigned int Spare1:2; 
        unsigned int opcode:4; 
        unsigned int grp:2;
        unsigned int dumy:2; // Assuming that dummy is also a padding
    } cmd;
    uint16_t word;
} Cmd; 

重要的是要注意捕获此类错误的方法只是通过查看处理器的内存,在声明为此联合类型的变量(或常量)的内存分配。我们应该在位字段之后改变位字段并查看物理存储器中的变化的影响。