是否可以将一种类型的位域转换为具有相同总位数的另一种类型的位域?
Is it possible to cast one type of bitfield to another type of bitfield with the same total number of bits?
任何人都可以告诉是否可以将一种类型的位域分配给另一种类型?支持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
目标是单词等于整个命令(word = command
)所以我们看起来像这样:
| word |
000010001100000
你可能想要的是联合:
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);
}
由于位域布局依赖于编译器,我不确定您在期待什么。
以下代码段可能包含未定义的行为,但我想这就是您要查找的内容。
Word word;
Command cmd;
cmd.grp = 2;
union
{
Word word;
Command cmd;
} u;
u.cmd = cmd;
word = u.word;
如果位字段由编译器从位 0 开始分配,那么 "word" 和 "cmd" 都将占用位 0:14 是合理的。
如果编译器从第15位开始分配位域(或者可能是第31位,这是大多数DSP处理器编译器的普遍情况)那么"word"和"cmd"都会占用位 15:1(或 31:17,如果是 32 位字)。
因此,为了将位字段结构完成为编译器分配的字大小,避免添加其他位似乎没问题。
不过这样做是个好习惯。
如果编译器的 "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;
那么union应该这样写
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;
重要的是要注意,捕获此类错误的方法很简单,就是查看处理器的内存,查看声明为该联合类型的变量(或常量)的内存分配.我们应该一个接一个地更改位域,并查看更改对物理内存的影响。
任何人都可以告诉是否可以将一种类型的位域分配给另一种类型?支持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
目标是单词等于整个命令(word = command
)所以我们看起来像这样:
| word |
000010001100000
你可能想要的是联合:
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);
}
由于位域布局依赖于编译器,我不确定您在期待什么。
以下代码段可能包含未定义的行为,但我想这就是您要查找的内容。
Word word;
Command cmd;
cmd.grp = 2;
union
{
Word word;
Command cmd;
} u;
u.cmd = cmd;
word = u.word;
如果位字段由编译器从位 0 开始分配,那么 "word" 和 "cmd" 都将占用位 0:14 是合理的。
如果编译器从第15位开始分配位域(或者可能是第31位,这是大多数DSP处理器编译器的普遍情况)那么"word"和"cmd"都会占用位 15:1(或 31:17,如果是 32 位字)。
因此,为了将位字段结构完成为编译器分配的字大小,避免添加其他位似乎没问题。
不过这样做是个好习惯。
如果编译器的 "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;
那么union应该这样写
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;
重要的是要注意,捕获此类错误的方法很简单,就是查看处理器的内存,查看声明为该联合类型的变量(或常量)的内存分配.我们应该一个接一个地更改位域,并查看更改对物理内存的影响。