老调重弹(1) - 如何正确地使用pragma pack改变结构填充字节数?

老调重弹(1) - 如何正确地使用pragma pack改变结构填充字节数?

结构填充(structure packing)或者结构域对齐问题(alignment of member of structures)早已有很成熟的解决方法。因为最近在做一个项目时看到一个头文件使用 #pragma pack(1) 改变了缺省设置而不恢复,所以再提一下。

  • 尽量让编译器来选择;
  • 如果改变了 structure alignment 的缺省设置,一定要恢复;
  • 尽量只改变需要的地方, #pragma pack 可以只改变一个数据结构的对齐属性;

字节对齐的值如果选择不合适,可能会严重影响程序性能。基于此原因,如果某个结构被大量频繁使用,就需要仔细安排结构中域的顺序。

方法一 直接使用pragma pack

MSVC/C++6.0可用如下方法设置与恢复:

#pragma pack(push, n)

#pragma pack(pop)

GCC下也可用同样的方法。

方法二 使用单独的头文件

如果需要考虑平台的可移植性,另一种方法也可用,即用单独的头文件来处理。在VC下有如下4个头文件:

pshpack1.h, pshpack2.h, pshpack4.h pshpack8.h用来分别设置1/2/4/8字节对齐,用poppack.h来恢复。实际使用时只需要include就可以了,如:

//在开头合适地方

#include <pshpack2.h>

...... 

//在结尾合适地方

#include <poppack.h>

这种方法的好处是万一某个编译器所支持的pragma pack用法不一样时,只需要修改这几个文件就可以了。如果一个项目有成百上千个源文件时,这种方法比较合适。

 

方法三 显示填充而不使用pragma
如:
struct S {
char c1;
int i;
char c2;
double d;
};
可以增加适当的填充字节:
struct S {
char c1;                               /* byte 0 */
char pad1,pad2,pad3;         /* bytes 1 through 3 */
int i;                                    /* bytes 4 through 7 */
char c2;                               /* byte 8 */
char pad9,pad10,pad11,     /* bytes 9 */
pad12,pad13,pad14,           /* through */
pad15;                                 /* 15 */
double d;                             /* bytes 16 through 23 */
};
此例子来自: http://www.aero.lr.tudelft.nl/facilities/manuals/ansic/portability.html#RN.CVT.NN535

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值