missing closing parenthesis at end of #pragma

环境为Tornado2.2,VxWorks5.5

编译出现警告如下:

warning: missing closing parenthesis at end of #pragma

warning: Unrecognised value for #pragma pack directive.

warning: malformed `#pragma pack'

 
有问题的代码如下:

#ifndef _CFE_

#pragma pack(1)

#endif
 

typedefstruct _ROBO_PORT_CTRL_STRUC

{
    unsigned char    rx_disable;
    unsigned short    tx_disable;
} ROBO_PORT_CTRL_STRUC;
 

#ifndef _CFE_

#pragma pack()

#endif
 

问题出在编译的预处理指令#pragma上,在C语言中,预处理指令#pragma pack(n)是负责确定结构类型数据结构体内各个变量在内存中地址对齐方式的,第一、如果n大于等于结构体中长度最大的变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。更加详细的内容请自己Google之。

对于本例来说,如果设置了#pragma pack(1),则:

sizeof(ROBO_PORT_CTRL_STRUC) = 3
 

如果没有设置#pragma pack(1),则:

sizeof(ROBO_PORT_CTRL_STRUC) = 4
 
一般情况下使用编译器缺省的对齐方式即可,但是总有些例外情况需要设置#pragma pack()参数,但是设置完了以后,想要恢复到原来缺省的对齐方式怎么办?因为Tornado实际上使用的是GCC编译器,因此查找了一下GCC的帮助,原文如下(中文是我自己的翻译):

1、#pragma pack(n) simply sets the new alignment.

#pragma pack(n),就是设置新的对齐方式为n

2、#pragma pack() sets the alignment to the one that was in effect when compilation started (see also command-line option -fpack-struct[=n] see Code Gen Options).

#pragma pack(),将对齐方式恢复为原来的初始值(可以参见命令行编译选项-fpack-struct[=n])

3、#pragma pack(push[,n]) pushes the current alignment setting on an internal stack and then optionally sets the new alignment.

#pragma pack(push[,n]),将当前的对齐方式存入内部堆栈,然后设置新的对齐方式为n

4、#pragma pack(pop) restores the alignment setting to the one saved at the top of the internal stack (and removes that stack entry). Note that #pragma pack([n]) does not influence this internal stack; thus it is possible to have #pragma pack(push) followed by multiple #pragma pack(n) instances and finalized by a single #pragma pack(pop).

#pragma pack(pop),恢复堆栈内保存的对齐方式,需要注意的是,单独使用#pragma pack([n])指令它只设置新的对齐方式,而不会把当前对齐方式放入堆栈。可以用#pragma pack(push)指令将当前的对齐方式入栈,然后再使用#pragma pack([n])指令设置新的对齐方式,最后使用#pragma pack(pop)恢复原来的设置。

 
从上面的说明可以总结出如下的几种配对使用方式,并附上在Tornado2.2,VxWorks5.5的环境下的编译结果:
 
使用方法
编译结果
1
#pragma pack(push)
#pragma pack(1)
……
#pragma pack(pop)
有警告,发生在#pragma pack(pop)那一行,内容如下:

missing closing parenthesis at end of #pragma

Extraneous characters at end of #pragma pack

Unrecognised value for #pragma pack directive.

malformed `#pragma pack'
2
#pragma pack(push,1)
……
#pragma pack(pop)
有警告,发生在#pragma pack(push,1)和#pragma pack(pop)这两行,内容同上
3
#pragma pack(push)
#pragma pack(1)
……
#pragma pack()
有警告,发生在#pragma pack()那一行,内容同上
4
#pragma pack(push,1)
……
#pragma pack()
有警告,发生在#pragma pack(push,1)和#pragma pack()这两行,内容同上
 
上表的运行结果说明如下:
 
使用方法
运行结果说明
1
#pragma pack(push)
#pragma pack(1)
……
#pragma pack(pop)
#pragma pack(1)指令起作用,后续结构体定义按照新的对齐方式进行对齐,而#pragma pack(pop)不起作用,后续的结构体依然按照#pragma pack(1)的方式对齐
2
#pragma pack(push,1)
……
#pragma pack(pop)
#pragma pack(push,1)不起作用,依然按照缺省方式对齐。
3
#pragma pack(push)
#pragma pack(1)
……
#pragma pack()
#pragma pack(1)指令起作用,后续结构体定义按照新的对齐方式进行对齐,而#pragma pack()不起作用,后续的结构体依然按照#pragma pack(1)的方式对齐
4
#pragma pack(push,1)
……
#pragma pack()
#pragma pack(push,1)不起作用,依然按照缺省方式对齐。
 
从上面两张表可以看出,不管是哪种组合方式,都有编译警告,而且都没有真正达到设置和恢复对齐方式的目的,但是这也就是网上所能找到的最多的解决方案了。 

经过多次试验和研究,终于发现使用#pragma pack(0)就没有编译错误,而且可以实现恢复缺省的对齐方式。

最后声明,本解决方案是在Tornado2.2 + VxWorks5.5下编译测试通过,其它环境没有测试,上述结果仅供参考。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值