missing closing parenthesis at end of #pragma

环境为Tornado2.2,VxWorks5.5数据结构

编译出现警告以下:ide

warning: missing closing parenthesis at end of #pragma测试

warning: Unrecognised value for #pragma pack directive.this

warning: malformed `#pragma pack'spa

 
有问题的代码以下:

#ifndef _CFE_命令行

#pragma pack(1)翻译

#endif
 

typedefstruct _ROBO_PORT_CTRL_STRUCrest

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

#ifndef _CFE_orm

#pragma pack()xml

#endif
 

问题出在编译的预处理指令#pragma上,在C语言中,预处理指令#pragma pack(n)是负责肯定结构类型数据结构体内各个变量在内存中地址对齐方式的,第1、若是n大于等于结构体中长度最大的变量所占用的字节数,那么偏移量必须知足默认的对齐方式,第2、若是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的帮助,原文以下(中文是我本身的翻译):

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

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

二、#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])

三、#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

四、#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下编译测试经过,其它环境没有测试,上述结果仅供参考。

相关文章
相关标签/搜索