结构体字节对齐
Posted 旧年不在cd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结构体字节对齐相关的知识,希望对你有一定的参考价值。
结构体字节对齐
一、为什么需要字节对齐?
- 总的来说,字节对齐的目的是为了提高数据的读写效率。例如有的硬件平台要求数据的起始地址必须从偶数开始,如果数据被放在了计数地址,读写的时候就需要耗费两个总线周期,而存放在偶数地址的只需要一个总线周期就可以。
二、如何改变默认的字节对齐方式?
- 结构体内存对齐字节可以通过#pragma pack(n) 的方式来指定
#pragma pack(4) //强制4字节对齐
struct C
double d;
char b;
int a;
short c;
;
#pragma pack() //恢复默认的对齐方式
struct B
double d;
char b;
int a;
short c;
;
-
#pragma pack() 能够取消自定义的对齐方式,恢复默认对齐
-
#pragma pack(push) 和#pragma pack(pop) 的问题
#pragma pack(push) //编译器编译到此处时将保存对齐状态(保存的是push指令之前的对齐状态)
#pragma pack(4)
struct CC
double d;
char b;
int a;
short c;
;
#pragma pack(pop) //编译器编译到此处时将恢复push指令前保存的对齐状态(请在使用该预处理命令之前使用#pragma pack(push))
struct BB
double d;
char b;
int a;
short c;
;
-
#pragma pack() 取消自定义对齐方式,恢复默认方式,而push之后pop是回到push指令之前的对齐方式
-
#pragma pack(show)
以警告信息的形式显示当前字节对齐的值
- #pragma pack(push, n)
先将当前字节对齐值压入编译栈栈顶,然后再将 n 设为当前值
- #pragma pack(pop, n)
将编译栈栈顶的字节对齐值弹出,然后丢弃,再将 n 设为当前值
- #pragma pack(push, identifier)
将当前字节对齐值压入编译栈栈顶,然后将栈中保存该值的位置标识为 identifier
- #pragma pack(pop, identifier)
将编译栈栈中标识为 identifier 位置的值弹出,并将其设为当前值。注意,如果栈中所标识的位置之上还有值,那会先被弹出并丢弃
- #pragma pack(push, identifier, n)
将当前字节对齐值压入编译栈栈顶,然后将栈中保存该值的位置标识为 identifier,再将 n 设为当前值
- #pragma pack(pop, identifier, n)
将编译栈栈中标识为 identifier 位置的值弹出,然后丢弃,再将 n 设为当前值。注意,如果栈中所标识的位置之上还有值,那会先被弹出并丢弃。
注意:如果在栈中没有找到 pop 中的标识符,则编译器忽略该指令,而且不会弹出任何值
以上是关于结构体字节对齐的主要内容,如果未能解决你的问题,请参考以下文章