struct struct_name {type [member_name] : width;
};
- 一般定义结构体,成员都是int、char等类型,占用的空间大小是固定的
- 在成员名称后用冒号来指定位宽,可以指定每个成员所占用空间,并且也不用受结构体成员起始地址对齐的限制
2、通过代码分析
2.1、不使用结构体位段
2.2、使用结构体位段
2.3、代码分析
- 得到汇编代码的命令:
- riscv64-unknown-elf-gcc test.c
- riscv64-unknown-elf-objdump -dS ./a.out > test.dis
- 2.1和2.2中的C语言代码除了结构体是否使用位段定义的区别外,并没有其他区别,但是通过反汇编文件可知,使用了结构体位段翻译出的汇编语句会更多
- 使用了结构体位段,每个结构体所占空间会更少
- 使用结构体位段,本质上就是降低C代码程序员的编程难度,将部分工作交给编译器完成
- 比如上面的例子,使用结构体位段后,不同成员的位宽不一样,编译器在将C代码转换成汇编代码时,就会添加一些移位操作、与或操作,这些操作C代码程序员自己来完成也是可以实现的
3、结构体位段的优劣势
- 使用位段的优势:
- 结构体的大小比较小,成员排布紧密,定义结构体变量时所占空间小,可以节省内存
- 使用位段,只是结构体定义有差别,对于访问结构体成员变量的方式并没有区别
- 使用位段的劣势:
- C语言代码虽然并没有区别,但是编译出的汇编代码会更多,编译出的elf/bin文件会更大
- 位段合适的使用场景:
- 设备的flash比较大,ram比较小:
- 可以接受烧录文件大一些,但是希望变量占用的内存小一些
- 相同功能,使用位段后要执行的汇编代码会更多,性能也会有下降
- 用于协议头解析:
- 在通信中,协议头解析是很常见的,有的协议头就是每个字段占几个bit,如果使用char、int等常规变量类型类定义结构体,无法和协议头的内容保持对齐
- 按照协议头中各字段所占的bit位来定义结构体位段,可以很方便的解析出协议头中各字段的数值,C代码写起来简单易懂