#pragma pack(N) 导致的一个问题

同事在使用第三方sdk时,总是不能获取正确的结果,但是验证第三方提供的demo又是可以成功获取的,同样的SDK为什么会导致不同的结果?。同事几天调试未果于是找到我,问我有没有遇到过这个问题。

先说下该数据结构体类型  64 + 4 + 4 + 4 + 8 + 8,出问题的地方在最后两个参数,这里前一个参数作A(64位),后一个参数作B(64位),在调用函数之前有个赋值操作

int_64 = int_32; 这里把给A赋值的变量名称作C(32位),给B赋值的变量名称作D(32位)。

当时看到同事已经做了打印,调用函数前打印A,B的值都没有问题,但是被调用函数内部打印的A,B的值不正常。打印的是用十进制,没有看出端倪,让同事改成十六进制显示,发现一个问题,A里的值是D的值向左偏移32位获得的值(oxD0000),B里的值看不到规律。

该程序是在VC环境中编译的,使用小端模式,这里以左边为低地址,右边为高地址,AB应该在被调用的函数理解为 


但是实际打印结果来看在被调用函数理解成了


即向右偏移了四个字节.

这里就开始怀疑字节对齐的问题了,但是查看两个程序(同事的程序和demo程序)使用的字节对齐方式都是默认对齐,都是8字节对齐。为什么同样方式的字节对齐结果不对?当时还是坚持了认定是字节对齐问题,分别又打印了结构体的sizeof,结果同事的程序是92,demo程序是96. 后来查问题遇到了瓶颈,为了同事顺利测试程序,让其在

A参数前面增加了一个4字节变量,此时结构体内容为 64 + 4 + 4 + 4 + 4 + 8 + 8,  函数可以获取结果了。

后来就思考按照8字节对齐方式,原结构体应该长度为96的,现在为92,说明没有起作用,然后按照没起作用的思路找到在使用这个第三方sdk头文件之前还包含了另外多个客户的sdk头文件,而恰恰这些头文件中有的定义了#pragma pack(4), #pragma pack(1), 覆盖了编译器设置的对齐选项。 至此所有问题都有了答案,最终该问题解决方式是在这个第三方sdk头文件中加入#pragma pack(8)。 

如何能避免类似的问题呢,如何限定#pragma pack(N)的范围暂时还没有想到方法,范围问题可以联想到不同类型变量的生命周期与namespace,程序设计时应尽量减少一个设置对其他单元的影响。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值