missing closing parenthesis at end of #pragma
環(huán)境為Tornado2.2,VxWorks5.5
編譯出現(xiàn)警告如下:
| warning: missing closing parenthesis at end of #pragma warning: Unrecognised value for #pragma pack directive. warning: malformed `#pragma pack' |
| #ifndef _CFE_ #pragma pack(1) #endiftypedefstruct _ROBO_PORT_CTRL_STRUC { unsigned charrx_disable; unsigned shorttx_disable; } ROBO_PORT_CTRL_STRUC;#ifndef _CFE_ #pragma pack() #endif |
問(wèn)題出在編譯的預(yù)處理指令#pragma上,在C語(yǔ)言中,預(yù)處理指令#pragma pack(n)是負(fù)責(zé)確定結(jié)構(gòu)類型數(shù)據(jù)結(jié)構(gòu)體內(nèi)各個(gè)變量在內(nèi)存中地址對(duì)齊方式的,第一、如果n大于等于結(jié)構(gòu)體中長(zhǎng)度最大的變量所占用的字節(jié)數(shù),那么偏移量必須滿足默認(rèn)的對(duì)齊方式,第二、如果n小于該變量的類型所占用的字節(jié)數(shù),那么偏移量為n的倍數(shù),不用滿足默認(rèn)的對(duì)齊方式。結(jié)構(gòu)的總大小也有個(gè)約束條件,分下面兩種情況:如果n大于所有成員變量類型所占用的字節(jié)數(shù),那么結(jié)構(gòu)的總大小必須為占用空間最大的變量占用的空間數(shù)的倍數(shù);否則必須為n的倍數(shù)。更加詳細(xì)的內(nèi)容請(qǐng)自己Google之。
對(duì)于本例來(lái)說(shuō),如果設(shè)置了#pragma pack(1),則:
sizeof(ROBO_PORT_CTRL_STRUC) = 3如果沒(méi)有設(shè)置#pragma pack(1),則:
sizeof(ROBO_PORT_CTRL_STRUC) = 4 一般情況下使用編譯器缺省的對(duì)齊方式即可,但是總有些例外情況需要設(shè)置#pragma pack()參數(shù),但是設(shè)置完了以后,想要恢復(fù)到原來(lái)缺省的對(duì)齊方式怎么辦?因?yàn)門ornado實(shí)際上使用的是GCC編譯器,因此查找了一下GCC的幫助,原文如下(中文是我自己的翻譯):1、#pragma pack(n) simply sets the new alignment.
#pragma pack(n),就是設(shè)置新的對(duì)齊方式為n2、#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(),將對(duì)齊方式恢復(fù)為原來(lái)的初始值(可以參見(jiàn)命令行編譯選項(xiàng)-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]),將當(dāng)前的對(duì)齊方式存入內(nèi)部堆棧,然后設(shè)置新的對(duì)齊方式為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),恢復(fù)堆棧內(nèi)保存的對(duì)齊方式,需要注意的是,單獨(dú)使用#pragma pack([n])指令它只設(shè)置新的對(duì)齊方式,而不會(huì)把當(dāng)前對(duì)齊方式放入堆棧??梢杂?pragma pack(push)指令將當(dāng)前的對(duì)齊方式入棧,然后再使用#pragma pack([n])指令設(shè)置新的對(duì)齊方式,最后使用#pragma pack(pop)恢復(fù)原來(lái)的設(shè)置。
從上面的說(shuō)明可以總結(jié)出如下的幾種配對(duì)使用方式,并附上在Tornado2.2,VxWorks5.5的環(huán)境下的編譯結(jié)果:| 使用方法 | 編譯結(jié)果 | |
| 1 | #pragma pack(push) #pragma pack(1) …… #pragma pack(pop) | 有警告,發(fā)生在#pragma pack(pop)那一行,內(nèi)容如下: 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) | 有警告,發(fā)生在#pragma pack(push,1)和#pragma pack(pop)這兩行,內(nèi)容同上 |
| 3 | #pragma pack(push) #pragma pack(1) …… #pragma pack() | 有警告,發(fā)生在#pragma pack()那一行,內(nèi)容同上 |
| 4 | #pragma pack(push,1) …… #pragma pack() | 有警告,發(fā)生在#pragma pack(push,1)和#pragma pack()這兩行,內(nèi)容同上 |
| 使用方法 | 運(yùn)行結(jié)果說(shuō)明 | |
| 1 | #pragma pack(push) #pragma pack(1) …… #pragma pack(pop) | #pragma pack(1)指令起作用,后續(xù)結(jié)構(gòu)體定義按照新的對(duì)齊方式進(jìn)行對(duì)齊,而#pragma pack(pop)不起作用,后續(xù)的結(jié)構(gòu)體依然按照#pragma pack(1)的方式對(duì)齊 |
| 2 | #pragma pack(push,1) …… #pragma pack(pop) | #pragma pack(push,1)不起作用,依然按照缺省方式對(duì)齊。 |
| 3 | #pragma pack(push) #pragma pack(1) …… #pragma pack() | #pragma pack(1)指令起作用,后續(xù)結(jié)構(gòu)體定義按照新的對(duì)齊方式進(jìn)行對(duì)齊,而#pragma pack()不起作用,后續(xù)的結(jié)構(gòu)體依然按照#pragma pack(1)的方式對(duì)齊 |
| 4 | #pragma pack(push,1) …… #pragma pack() | #pragma pack(push,1)不起作用,依然按照缺省方式對(duì)齊。 |
經(jīng)過(guò)多次試驗(yàn)和研究,終于發(fā)現(xiàn)使用#pragma pack(0)就沒(méi)有編譯錯(cuò)誤,而且可以實(shí)現(xiàn)恢復(fù)缺省的對(duì)齊方式。
最后聲明,本解決方案是在Tornado2.2 + VxWorks5.5下編譯測(cè)試通過(guò),其它環(huán)境沒(méi)有測(cè)試,上述結(jié)果僅供參考。
總結(jié)
以上是生活随笔為你收集整理的missing closing parenthesis at end of #pragma的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ASP.NET温故而知新学习系列之ASP
- 下一篇: 无线传输层安全协议WTLS安全机制详解