环境为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),则:
如果没有设置#pragma pack(1),则:
1、#pragma pack(n) simply sets the new alignment.
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).
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)恢复原来的设置。
|
使用方法
|
编译结果
|
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下编译测试通过,其它环境没有测试,上述结果仅供参考。