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下編譯測試經過,其它環境沒有測試,上述結果僅供參考。

相關文章
相關標籤/搜索