lby*_*san 4 c struct unions bit-fields
我是计算机科学专业的学生。
现在,我正在用C进行计算机架构项目,该项目可模拟处理器。
有很多类型的指令,例如
31 27 26 22 21 17 16 0
---------------------------------------------------------------
| op | ra | rb | imm17 |
---------------------------------------------------------------
31 27 26 22 21 17 16 7 6 5 4 0
---------------------------------------------------------------
| op | ra | rb | imm10 | m | shamt |
---------------------------------------------------------------
31 27 26 22 21 0
---------------------------------------------------------------
| op | ra | imm22 |
---------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
因此,我想制作一个C结构,其中包含与每个元素(例如op,ra等)相对应的位域。
起初,我认为我可以使用联合和嵌套结构。
例如,我编写了如下代码:
struct instr_t {
union {
uint32_t imm22 : 22;
struct {
union {
uint32_t imm17: 17;
struct {
uint8_t shamt: 5;
uint8_t mode : 2;
uint16_t imm10 : 10;
};
};
uint8_t rb : 5;
};
};
uint8_t ra : 5;
uint8_t op : 5;
}
Run Code Online (Sandbox Code Playgroud)
我期望sizeof(struct instr_t)的结果为4,但实际为12。
嵌套的结构也许有一些填充。
所以,这是我的要求:
要么
谢谢!
位域成员必须存储在相同的存储单元中,以进行连续布局:
struct instr_1_t {
uint32_t imm22 : 17;
uint32_t rb : 5;
uint32_t ra : 5;
uint32_t op : 5;
};
struct instr_2_t {
uint32_t shamt: 5;
uint32_t m: 2;
uint32_t imm10 : 10;
uint32_t rb : 5;
uint32_t ra : 5;
uint32_t op : 5;
};
struct instr_3_t {
uint32_t imm22 : 22;
uint32_t ra : 5;
uint32_t op : 5;
};
union instr_t {
struct {
uint32_t pad : 22;
uint32_t op : 5;
};
instr_1_t instr_1;
instr_2_t instr_2;
instr_3_t instr_3;
};
static_assert(sizeof(instr_t) == sizeof(uint32_t), "sizeof(instr_t) != sizeof(uint32_t)");
void handle_instr(instr_t i) {
switch(i.op) {
//
}
}
Run Code Online (Sandbox Code Playgroud)
马克西姆给出了正确答案。
我还建议查看此代码以了解为什么 sizeof instr_t 给出 12 :)
typedef struct s1{
uint8_t shamt: 5;
uint8_t mode : 2;
uint16_t imm10 : 10;
} s_1;
typedef union u1{
uint32_t imm17: 17;
s_1 member0;
} u_1;
typedef struct s2{
u_1 member1;
uint8_t rb : 5;
} s_2;
typedef union u2{
uint32_t imm22 : 22;
s_2 member3;
} u_2;
typedef struct instr_t {
u_2 member4;
uint8_t ra : 5;
uint8_t op : 5;
} s_instr;
int main(int argc, char* argv[])
{
printf("sizes s_1=%d, u_1=%d, s_2=%d, u_2=%d, s_instr=%d\n", sizeof(s_1), sizeof(u_1), sizeof(s_2), sizeof(u_2), sizeof(s_instr));
printf("uint8_t=%d, uint16_t=%d, uint32_t=%d\n", sizeof(uint8_t), sizeof(uint16_t), sizeof(uint32_t));
printf("Sizeof instr_t is %d\n", sizeof(s_instr));
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
干杯!