![VC(VisualC++)預(yù)處理及編譯_第1頁(yè)](http://file4.renrendoc.com/view/1ecc47e35216196a7767e1d7e7d699bd/1ecc47e35216196a7767e1d7e7d699bd1.gif)
![VC(VisualC++)預(yù)處理及編譯_第2頁(yè)](http://file4.renrendoc.com/view/1ecc47e35216196a7767e1d7e7d699bd/1ecc47e35216196a7767e1d7e7d699bd2.gif)
![VC(VisualC++)預(yù)處理及編譯_第3頁(yè)](http://file4.renrendoc.com/view/1ecc47e35216196a7767e1d7e7d699bd/1ecc47e35216196a7767e1d7e7d699bd3.gif)
![VC(VisualC++)預(yù)處理及編譯_第4頁(yè)](http://file4.renrendoc.com/view/1ecc47e35216196a7767e1d7e7d699bd/1ecc47e35216196a7767e1d7e7d699bd4.gif)
下載本文檔
版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
預(yù)處理器特殊術(shù)語(yǔ)在本書(shū)中,名詞“參量”指的是傳送給ー個(gè)函數(shù)的實(shí)體。有時(shí)候,它用“actuaF聯(lián)“forma「修飾,它們分別用于表示函數(shù)調(diào)用時(shí)的參量表達(dá)式和在函數(shù)定義時(shí)的參量說(shuō)明。名詞“變量’’指的是ー種簡(jiǎn)單的C類(lèi)型數(shù)據(jù)對(duì)象,名詞“對(duì)象”指的是C++對(duì)象和變量;它是ー個(gè)含義廣泛的名詞。翻譯階段C和C++程序由一個(gè)或多個(gè)源文件組成,它們都包含了程序的某些文本,ー個(gè)不包含代碼部分的源文件和它的包含文件(用#indude預(yù)處理器指令包含的文件),若被條件編譯指令(比如#if)調(diào)用,則稱(chēng)其為ー個(gè)“轉(zhuǎn)換單元”。源文件可被翻譯多次,翻譯過(guò)去的文件事實(shí)上是很正常的。已經(jīng)翻譯了的翻譯單元可保存在單獨(dú)的對(duì)象文件或?qū)ο蟠a庫(kù)里,這些單個(gè)的轉(zhuǎn)換單元可被連接形成一個(gè)可執(zhí)行文件或動(dòng)態(tài)鏈接庫(kù)(DLL)。轉(zhuǎn)換單元可采用下列形式通信:調(diào)用具有外部連接的函數(shù)。調(diào)用具有外部連接的類(lèi)成員函數(shù)。直接更改具有外部連接的對(duì)象。文件的直接更改。?內(nèi)部外理通信(僅限于基于MicrosoftWindows的應(yīng)用程序)。以下是編譯器翻譯文件的各個(gè)階段:字符映射源文件中的字符被映射為內(nèi)部源代碼的形式。此階段三字母序列被轉(zhuǎn)換為單字符的內(nèi)部表現(xiàn)形式。行拼接在此階段,源文件中所有以反斜杠(ヽ)結(jié)尾且其后緊跟ー換行符的行,將與下一行連接,從而由物理行生成邏輯行。所有非空源文件結(jié)束于ー個(gè)前面沒(méi)有反斜杠的換行符。語(yǔ)言符號(hào)化此階段源文件被分為預(yù)處理語(yǔ)言符號(hào)和空白字符。源文件中每個(gè)注釋被用ー個(gè)空白字符代替。換行符被保留。預(yù)處理此階段執(zhí)行預(yù)處理指令并將宏擴(kuò)展至源文件,#include語(yǔ)句調(diào)用對(duì)所有包括文本啟動(dòng)前面三個(gè)翻譯步驟開(kāi)頭的翻譯過(guò)程。字符集映射所有的源字符集成員和轉(zhuǎn)義序列將轉(zhuǎn)換為執(zhí)行字符集中的等價(jià)形式,對(duì)于MicrosoftC和C++來(lái)說(shuō),源字符集和執(zhí)行字符集都是ASCI!碼。字符串合并所有相鄰的字符串和寬字符文字都將被合并。例如:"String""concatenatiorT合并為''Stringconcatenation”。翻譯所有的語(yǔ)言符號(hào)將按語(yǔ)法和語(yǔ)義規(guī)則進(jìn)行分析;這些語(yǔ)言符號(hào)被轉(zhuǎn)換為目標(biāo)代碼。鏈接此階段所有的外部引用被分解以生成一個(gè)可執(zhí)行程序或ー個(gè)動(dòng)態(tài)鏈接庫(kù)。編譯器在翻譯過(guò)程中遇到語(yǔ)法錯(cuò)誤時(shí),將發(fā)出ー個(gè)警告或錯(cuò)誤信息。鏈接器分解所有的外部引用,并把ー個(gè)或多個(gè)分開(kāi)處理的轉(zhuǎn)換單元和標(biāo)準(zhǔn)庫(kù)聯(lián)接起來(lái),以生成一個(gè)可執(zhí)行程序或動(dòng)態(tài)鏈接庫(kù)(DLL)。預(yù)處理器指令預(yù)處理器指令如#define和#ifdef,一般被用在不同的運(yùn)行環(huán)境下,使源程序易于更改和編譯。源文件中的指令指示預(yù)處理器執(zhí)行特有的行為。例如,預(yù)處理器可替換文本中的語(yǔ)言符號(hào),將其它的文件內(nèi)容插入源文件中,或移走文本的一部分以抑制文件中某部分的編譯。預(yù)處理器行在宏擴(kuò)展之前被識(shí)別且執(zhí)行。不過(guò),如果宏擴(kuò)展看起來(lái)象一個(gè)預(yù)處理器指令,該命令將不能被預(yù)處理器識(shí)別。除轉(zhuǎn)義序列之外,預(yù)處理器語(yǔ)句采用與源文件語(yǔ)句相同的字符集。在預(yù)處理器語(yǔ)句中的字符集和可執(zhí)行程序的字符集是ー樣的。預(yù)處理器也可識(shí)別負(fù)字符值。預(yù)處理器可識(shí)別如下指令:#define#error#import#undef#elif#if#include#else#ifdef#line#endif#ifhdef#pragma數(shù)字符號(hào)片)是包含預(yù)處理器指令的行中的第一個(gè)非空白字符??瞻鬃址沙霈F(xiàn)在數(shù)字符號(hào)和指令的第一個(gè)字母之間。某些指令包含參量和值。指令之后的任何文本(除作為指令一部分的參量或值之外)必須放在單行注釋分界符(〃)之后或注釋分界符(/**/)之間。預(yù)處理器指令可出現(xiàn)在源文件的任何地方,但它們僅用于源文件的剩余部分。#define指令可以用#define指令給程序中的常量取ー個(gè)有意義的名稱(chēng),其語(yǔ)法的兩種形式如下:語(yǔ)法#define標(biāo)識(shí)符語(yǔ)言符號(hào)字符串opt#define標(biāo)識(shí)符[(標(biāo)識(shí)符。pt,…,標(biāo)識(shí)符opt)]語(yǔ)言符號(hào)字符串opt#define指令用語(yǔ)言符號(hào)字符串替換源文件中一個(gè)標(biāo)識(shí)符的所有出現(xiàn),標(biāo)識(shí)符僅在它形成ー個(gè)語(yǔ)言符號(hào)時(shí)被替換(參見(jiàn)“MicrosoftVisualC++6.0參考庫(kù)”的“MicrosoftVisualC++6.0語(yǔ)言參考手冊(cè)”卷的第1章“詞法規(guī)定”中的“語(yǔ)言符號(hào)”)。例如,若標(biāo)識(shí)符出現(xiàn)在ー個(gè)注釋、ー個(gè)字符串或作為ー個(gè)長(zhǎng)標(biāo)識(shí)符的一部分之中,它就不被替換。ー個(gè)不帶語(yǔ)言符號(hào)字符串的#define指令將移走源文件中每次標(biāo)識(shí)符的出現(xiàn)。標(biāo)識(shí)符保留其定義且能用#defined和#ifdef測(cè)試。語(yǔ)言符號(hào)字符串參量由一系列語(yǔ)言符號(hào)組成,如關(guān)鍵字、常量或完整的語(yǔ)句。一個(gè)或多個(gè)空白字符可將語(yǔ)言符號(hào)字符串和標(biāo)識(shí)符分開(kāi)??瞻鬃址粫?huì)被認(rèn)為是被替換文本的一部分,文本最后語(yǔ)言符號(hào)之后的空白也不會(huì)認(rèn)為是替換文本的一部分。形式參數(shù)名稱(chēng)出現(xiàn)在語(yǔ)言符號(hào)字符串中以標(biāo)志出實(shí)際值被替換的位置,每個(gè)參數(shù)名稱(chēng)可在語(yǔ)言符號(hào)字符串中出現(xiàn)多次,且可以以任何次序出現(xiàn)。調(diào)用時(shí)參量的數(shù)目必須與宏定義的參數(shù)數(shù)目相匹配。圓括號(hào)的自由運(yùn)用可確保正確地說(shuō)明復(fù)雜的實(shí)際參量。用第二種語(yǔ)法形式可創(chuàng)建類(lèi)似函數(shù)的宏。這種形式接受一個(gè)用圓括號(hào)括起的可選參數(shù)表。在最初定義之后引用該標(biāo)識(shí)符,可以使用實(shí)際參量替代形式參數(shù)的語(yǔ)言符號(hào)字符串參量的形式,來(lái)替換標(biāo)識(shí)符(標(biāo)識(shí)符opt,…,標(biāo)識(shí)符opt)的每次出現(xiàn)。表中的形式參數(shù)必須用逗號(hào)隔開(kāi)。該表中的每個(gè)名稱(chēng)都必須是唯一的,且此參量表必須包括在圓括號(hào)中,標(biāo)識(shí)符和左邊的圓括號(hào)之間不能有空格。對(duì)于占用多行的長(zhǎng)指令可使用行連接,把反斜杠(ヽ)放在換行符前。形式參數(shù)名稱(chēng)的范圍延伸到結(jié)束語(yǔ)言符號(hào)字符串的換行符。當(dāng)一個(gè)宏以第二種語(yǔ)法形式定義時(shí),參量表后的文本實(shí)例就構(gòu)成一個(gè)宏調(diào)用。在源文件中,一個(gè)標(biāo)識(shí)符實(shí)例后的實(shí)際參量必須與宏定義的相應(yīng)形式參數(shù)匹配。每個(gè)語(yǔ)言符號(hào)字符串之前無(wú)字符串化片)、字符化(#@)或語(yǔ)言符號(hào)粘貼併#)操作符,或其后無(wú)##操作符的形式參量,都被相應(yīng)的實(shí)際參量所替換。在指令替換形式參數(shù)之前,實(shí)際參量中的任何宏都將被擴(kuò)展(本章之后的“預(yù)處理器操作符’’中將介紹這些操作符)。以下帶參量宏的例子說(shuō)明了#define語(yǔ)法的第二種形式:〃定義光標(biāo)行的宏#defineCURSOR(top,bottom)((top)?8)|bottom))〃獲取指定范圍中的一個(gè)隨機(jī)整數(shù)的宏#definegetrandom(min,max)\((rand()%(int)(((max)+l)-(min)))+(min))有副作用的參量有時(shí)會(huì)導(dǎo)致宏產(chǎn)生不希望的結(jié)果。ー個(gè)給定的形式參量在語(yǔ)言符號(hào)字符串中可能出現(xiàn)多次。如果該形式參數(shù)被ー個(gè)有副作用的表達(dá)式所替換,則該表達(dá)式及其副作用,可能被求值多次(參見(jiàn)本章后面“語(yǔ)言符號(hào)粘貼操作符##"中的例子)。#undef指令可使ー個(gè)標(biāo)識(shí)符的預(yù)處理器定義失效。有關(guān)的更多信息參見(jiàn)#undef指令。若一個(gè)被定義的宏名稱(chēng)出現(xiàn)在語(yǔ)言符號(hào)字符串中(即使是另一個(gè)宏擴(kuò)展的結(jié)果),它將不被擴(kuò)展。除非第二次定義(#define)宏與原定義完全相同,否則重定義ー個(gè)已定義過(guò)的宏將產(chǎn)生一個(gè)錯(cuò)誤信息。Microsoft特殊處MicrosoftC/C++允許ー個(gè)宏的重定義,但會(huì)產(chǎn)生一個(gè)警告信息,說(shuō)明新的定義與原定義相同。ANSIC認(rèn)為宏的重定義是錯(cuò)誤的。例如,下面的宏對(duì)C/C++是相同的,但會(huì)產(chǎn)生一個(gè)警告信息:#definetest(fl,f2)(fl*f2)#definetest(al,a2)(al*a2)Microsoft特殊處結(jié)束這個(gè)例子用于說(shuō)明#define指令:#defineWIDTH80#defineLENGTH(WIDTH+10)第一個(gè)說(shuō)明定義標(biāo)識(shí)符WIDTH為整形常量80,且用WIDTH和整形常量10定義LENGTH。LENGTH的每次出現(xiàn)都用(WIDTH+I0)所替換,接著,WIDTH+IO的每次出現(xiàn)都用表達(dá)式(80+10)替換。WIDTH+10的圓括號(hào)非常重要,因?yàn)樗鼈儧Q定著如下語(yǔ)句的解釋。vakLENGTH*20;經(jīng)預(yù)處理后該語(yǔ)句變?yōu)?vak(80+10)*20;求得值為1800,若無(wú)括號(hào),結(jié)果為:var=80+10*20其值為280〇Microsoft特殊處在文件開(kāi)頭用/D編譯器選項(xiàng)定義宏和常量,和用ー個(gè)#define預(yù)處理指令效果是ー樣的。能用/D選項(xiàng)定義的宏可達(dá)30個(gè)。Microsoft特殊處結(jié)束#error指令采用error指令可產(chǎn)生編譯錯(cuò)誤信息。語(yǔ)法#error語(yǔ)言符號(hào)字符串錯(cuò)誤消息包括語(yǔ)言符號(hào)字符串參量,且從屬于宏擴(kuò)展。這些指令對(duì)于檢測(cè)程序的前后矛盾和預(yù)處理時(shí)的違犯約束是非常有用的,以下例子說(shuō)明了預(yù)處理時(shí)的出錯(cuò)處理:#if!defined(_cplusplus)#errorC++compilerrequired.#endif當(dāng)遇到#error指令時(shí),編譯終止。#if,#elif,#else和#endif指令#if、#elif、#else和#endif指令控制源文件中某部分的編譯。如果表達(dá)式併if之后)有一個(gè)非〇值,則緊跟在#if指令之后的行組將保留在轉(zhuǎn)換單元中。語(yǔ)法條件的:if部分elif部分optelse部分optendif行if部分:if行文本if行:#if常量表達(dá)式#ifhdef標(biāo)識(shí)符elif部分:elif行文本elif部分elif行文本elif行:#elif常量表達(dá)式else部分:else行文本else行:#elseendif行:#endif源文件中每個(gè)#if指令都必須與最近的ー個(gè)#endif相匹配。在#if和#endif指令之前的#elif指令的數(shù)目是不限的,但最多只能有一個(gè)#else指令。#else必須是#endif之前的最后ー個(gè)指令。#if、#elif、#else和#endif指令可嵌套在其它#if指令的文本部分。每個(gè)嵌套的#else、#elif或#endif指令應(yīng)屬于前面最近的ー個(gè)#if指令。所有的條件編譯指令,如#if和#ifdef,必須與文件結(jié)束前最近的#endif指令匹配;否則,將產(chǎn)生一個(gè)錯(cuò)誤消息。當(dāng)條件編譯指令包括在包含文件中時(shí),他們必須滿(mǎn)足相同的條件:在包含文件結(jié)尾沒(méi)有不匹配的條件編譯指令。宏替換應(yīng)在#elif命令后的命令行部分內(nèi)進(jìn)行,因此一個(gè)宏調(diào)用可用在常量表達(dá)式中。預(yù)處理器選擇ー個(gè)給定文本的出現(xiàn)之一作進(jìn)ー步的處理。文本中指定的ー個(gè)塊可以是文本的任何序列。它可能占用一行以上。通常該文本是對(duì)于編譯和預(yù)處理器有意義的程序文本。預(yù)處理器處理選擇文本并將其傳送給編譯器。若該文本包含預(yù)處理器指令,預(yù)處理器將執(zhí)行這些指令。編譯器只編譯預(yù)處理器選定的文本塊。預(yù)處理器通過(guò)求值每個(gè)#if或#elif指令之后的常量表達(dá)式直到找到ー個(gè)為真(非0)的常量表達(dá)式來(lái)選擇單個(gè)文本項(xiàng)。預(yù)處理器選擇所有的文本(包括以#開(kāi)頭的其它預(yù)處理器指令)直到它關(guān)聯(lián)的#elif、#else或#endif。如果常量表達(dá)式的所有出現(xiàn)都為假,或者如果沒(méi)有#elif指令,預(yù)處理器將選擇#else后的文本塊。如果#else被忽略,且所有#if塊中的常量表達(dá)式都為假,則不選擇任何文本塊。常量表達(dá)式是一個(gè)有以下額外限制的整型常量表達(dá)式:表達(dá)式必須是整型且可以包括整型常量,字符常量和defined操作符。表達(dá)式不能使用sizeof或一個(gè)類(lèi)型造型操作符。目標(biāo)環(huán)境不能表示整數(shù)的所有范圍。在翻譯表示中,int類(lèi)型和10ng類(lèi)型以及unsignedint類(lèi)型和unsignedlong類(lèi)型是相同的。翻譯器可將字符常量翻譯成一組不同于目標(biāo)環(huán)境的代碼值。為了確定目標(biāo)環(huán)境的屬性,應(yīng)在為目標(biāo)環(huán)境建立的應(yīng)用程序中檢測(cè)LIMITS.H的宏值。表達(dá)式不需執(zhí)行所有的環(huán)境查詢(xún),但需與目標(biāo)計(jì)算機(jī)的執(zhí)行過(guò)程細(xì)節(jié)隔離開(kāi)。預(yù)處理器操作符defined可用于特殊的常量表達(dá)式,語(yǔ)法如下:語(yǔ)法defined(標(biāo)識(shí)符)defined標(biāo)識(shí)符若此標(biāo)識(shí)符當(dāng)前已定義,則該常量表達(dá)式被認(rèn)為是真(非〇);否則,條件為假(0)。ー個(gè)定義為空文本的標(biāo)識(shí)符可認(rèn)為已定義。defined指令只能用于#if和#endif指令。在如下例子中,#if和#endif指令控制著三個(gè)函數(shù)調(diào)用中某ー個(gè)的編譯:ifdefined(CREDIT)credit();#elifdefined(DEBIT)debit();#elseprinterror();#endif若標(biāo)識(shí)符CREDIT已定義,則對(duì)于credit的函數(shù)調(diào)用被編譯。若標(biāo)識(shí)符DEBIT被定義,則對(duì)于debit的函數(shù)調(diào)用被編譯。若未定義任何標(biāo)識(shí)符,將編譯對(duì)于printerror的函數(shù)調(diào)用。注意,在C和C++中,CREDIT和credit是不同的標(biāo)識(shí)符,因?yàn)樗鼈兊拇笮?xiě)不一樣。如下例子中的條件編譯語(yǔ)句給出了一個(gè)名稱(chēng)為DLEVEL的已定義的符號(hào)常量:defineSIGNAL1ifSTACKUSE==1#defineSTACK200#else#defineSTACK100#endif#else#defineSIGNAL0#ifSTACKUSE=l#defineSTACK100#else#defineSTACK50#endif#endif#ifDLEVEL=0#defineSTACK0#elifDLEVEL=l#defineSTACK100#elifDLEVEL>5display(debugptr)滸else#endif第一個(gè)#if塊中有兩組嵌套的#if、#else和#endif指令。第一組指令僅當(dāng)DLEVEL1>5為真時(shí)執(zhí)行;否則,執(zhí)行#else之后的語(yǔ)句。第二組中的#elif和#else指令選擇基于DLEVEL值的四個(gè)選項(xiàng)之ー。常量STACK依據(jù)DLEVEL定義為〇,100或20〇。若DLEVEL大于5,則編譯語(yǔ)句:#elifDLEVEL>5display(debugptr);且此時(shí)不定義STACK〇條件編譯一般用于防止同一頭文件的多重包含。C++中在頭文件內(nèi)經(jīng)常定義類(lèi)的位置,可使用如下結(jié)構(gòu)來(lái)防止多次定義。//EXAMPLE.H例子頭文件#if!defined(EXAMPLE_H)#defineExampleEHclassExample};#endif//!defined(EXAMPLE_H)上面的代碼用于檢查符號(hào)常量EXAMPLE_H是否已定義。若已定義,該文件就已被包括且不需再處理;如果未定義,常量EXAMPLE_H將被定義,以標(biāo)記EXAMPLE.H為已經(jīng)處理。Microsoft特殊處條件編譯表達(dá)式被看作為signedlong值,且這些表達(dá)式與C++中的表達(dá)式采用相同的規(guī)則求值。例如,表達(dá)式:#ifOxFFFFFFFFL>1UL為真。Microsoft特殊處結(jié)束#ifdef和ifndef指令#ifdef和#ifhdef指令與使用defined(標(biāo)識(shí)符)操作符的作用是ー樣的。語(yǔ)法#ifdef標(biāo)識(shí)符#ifhdef標(biāo)識(shí)符等同于#ifdefined標(biāo)識(shí)符#if!defined標(biāo)識(shí)符#if指令能用的任何地方都可以用#ifUef和#ifhdef指令。當(dāng)標(biāo)識(shí)符已被定義時(shí),#ifdef標(biāo)識(shí)符語(yǔ)句等同于#if1;而當(dāng)標(biāo)識(shí)符未定義或用#undef指令對(duì)其反定義時(shí),該語(yǔ)句等同于#if0。這些指令僅用于檢查C或C++源代碼中是否出現(xiàn)該標(biāo)識(shí)符,而不是用于檢查C或C++源程序中該標(biāo)識(shí)符的說(shuō)明。提供這幾個(gè)指令只為了與該語(yǔ)言的老版本兼容。目前的趨勢(shì)是偏向于采用defined(標(biāo)識(shí)符)定義常量表達(dá)式的#if指令。#ifhdef指令測(cè)試與#ifdef相反的條件。若標(biāo)識(shí)符未定義(或已用#undef反定義),其條件為真(非0);反之,條件為假(0)。Microsoft特殊處可以使用/D選項(xiàng)從命令行傳送標(biāo)識(shí)符,采用/D選項(xiàng)至多可以指定30個(gè)宏。檢查ー個(gè)定義是否存在是非常有用的,因?yàn)槎x可從命令行傳送。例如://prog.cpp#ifhdeftest〃這三個(gè)語(yǔ)句放在你的代碼中#definefinal#endifCL/Dtestprog.cpp〃這是編譯的命令Microsoft特殊處結(jié)束#import指令C-H"特殊處#import指令用于從ー個(gè)類(lèi)型庫(kù)中結(jié)合信息。該類(lèi)型庫(kù)的內(nèi)容被轉(zhuǎn)換為C++類(lèi),主要用于描述COM界面。語(yǔ)法#import”文件名"[屬性]#importく文件名>[屬性]屬性:屬性1,屬性2,...屬性1屬性2...文件名是ー個(gè)包含類(lèi)型庫(kù)信息的文件的名稱(chēng)。ー個(gè)文件可為如下類(lèi)型之ー個(gè)類(lèi)型庫(kù)(.TLB或.ODL)文件。ー個(gè)可執(zhí)行(.EXE)文件。ー個(gè)包含類(lèi)型庫(kù)資源(如.OCX)的庫(kù)文件(.DLL)。ー個(gè)包含類(lèi)型庫(kù)的復(fù)合文檔。其它可被LoadTypeLibAPI支持的文件格式。文件名之前可以有一個(gè)目錄規(guī)格。文件名必須是ー個(gè)已存在文件的名稱(chēng)。兩種格式的區(qū)別是當(dāng)路徑未完全說(shuō)明時(shí),預(yù)處理器檢索類(lèi)型庫(kù)文件的順序不同。動(dòng)作語(yǔ)法格式引號(hào)格式這種格式讓預(yù)處理器首先搜索與包含#import語(yǔ)句的文件同一目錄的類(lèi)型庫(kù)文件,然后在所有包括(include)該文件的目錄中搜索,最后在如下路徑中搜索尖括號(hào)格式這種格式指示預(yù)處理器沿以下路徑搜索類(lèi)型庫(kù)文件編譯器在以下目錄中搜索已命名的文件:.PATH環(huán)境變量路徑表。.LIB環(huán)境變量路徑表。.用/1(額外的包括目錄)編譯器選項(xiàng)指定的路徑。#import可以任選地包含ー個(gè)或多個(gè)屬性。這些屬性使編譯器改變類(lèi)型庫(kù)頭文件的內(nèi)容。ー個(gè)反斜杠。)符可用在ー個(gè)單ー的#import語(yǔ)句中包含額外的行,例如:#import"test.lib"no_namespace\rename("〇ldName","NewName")#import屬性列出如下:excludehigh_method_prefixhigh_property_prefixesimplementationonlyinclude(...)injectstatementnamedguidsno_auto_excludeno_implementationnonamespaceraw_dispinterfacesraw_interfaces_onlyraw_method_prefixrawnativetypesraw_property_prefixesrenamerename_namespace#import指令可創(chuàng)建兩個(gè)在C++源代碼中重構(gòu)類(lèi)型庫(kù)內(nèi)容的頭文件,第一個(gè)頭文件和用Microsoft接口定義語(yǔ)言(MIDL)編譯器生成的頭文件類(lèi)似,但有額外的編譯器生成代碼和數(shù)據(jù)。第一個(gè)頭文件與類(lèi)型庫(kù)有相同的基本名,其擴(kuò)展名為.TLH。第二個(gè)頭文件也有與類(lèi)型庫(kù)相同的基本名,其擴(kuò)展名為.TLI。它包括了編譯器生成成員函數(shù)的實(shí)現(xiàn),且被包含在併include)的第一個(gè)頭文件內(nèi)。兩個(gè)頭文件都在用/F。(命名對(duì)象文件)選項(xiàng)指定的輸出目錄中。隨后它們被讀出和編譯,就像第一個(gè)頭文件被#include指令命名ー樣。以下是伴隨#import指令的編譯器優(yōu)化:?頭文件被創(chuàng)建時(shí),將被分配與類(lèi)庫(kù)相同的時(shí)間標(biāo)志。?處理#import時(shí),編譯器首先測(cè)試頭文件是否存在,是否過(guò)期。若條件為真,就不需重新創(chuàng)建。編譯器延遲對(duì)于OLE子系統(tǒng)的初始化,直到碰到第一個(gè)#import命令。#import指令也可參與最小重建且可被置于ー個(gè)預(yù)編譯頭文件中?;绢?lèi)型庫(kù)頭文件基本類(lèi)型庫(kù)頭文件由七個(gè)部分組成:.頭部固定正文:由注釋、COMDEF.H(定義用在頭部的ー些標(biāo)準(zhǔn)宏)的include語(yǔ)句和其它繁雜的安裝信息組成。.前向引用和類(lèi)型定義:由象structIMyinterface之類(lèi)的結(jié)構(gòu)說(shuō)明和用于ー些TKIND_ALIAS項(xiàng)的類(lèi)型定義組成。.靈敏指針說(shuō)明:模塊類(lèi)_com_ptr_t是ー個(gè)封裝接口指針和消除調(diào)用AddRef、Release和Queryinterface函數(shù)需求的靈敏指針實(shí)現(xiàn)。此外,它隱藏了創(chuàng)建一個(gè)新COM對(duì)象中的CoCreatelnstance調(diào)用。此部分采用宏語(yǔ)句_COM_SMARTPTRTYPEDEF將COM接ロ的類(lèi)型定義創(chuàng)建為_(kāi)com_ptr_t模板類(lèi)的模板特例化。例如,對(duì)于界面IFoo,.TLH文件包含有:_COM_SMARTPTRTYPEDEF(IFoo,__uuidof(IFoo));編譯器將其擴(kuò)展為:typedefcomptrt<comIIID<IFoo, uuidof(IFoo)?IFooPtr;類(lèi)型IFooPtr可以用在原始的界面指針I(yè)Foo?的地方。結(jié)果,就不需調(diào)用各種IUnknown成員函數(shù)。.類(lèi)型信息(typeinfo)說(shuō)明:主要由類(lèi)定義和其它項(xiàng)組成,這些項(xiàng)說(shuō)明由ITyptLib:GetTypeInfo返回的單個(gè)的信息類(lèi)型項(xiàng)目。在這部分,每個(gè)來(lái)自于類(lèi)型庫(kù)的信息類(lèi)型都以一種依賴(lài)于TYPEKIND信息的格式反映在該頭部。.任選舊式GUID定義:包含命名的GUID常量的初始化過(guò)程,這些定義是格式CLSID_CoClass和HD」nterface的名稱(chēng),與那些由MIDL編譯器產(chǎn)生的類(lèi)似。.用于第二個(gè)類(lèi)型庫(kù)頭部的#include語(yǔ)句。.結(jié)尾固定正文:目前包括#pragmapack(pop)。以上這些部分除頭部固定正文和結(jié)尾固定正文部分之外,都被包括在原來(lái)的IDL文件中以library語(yǔ)句指定其名稱(chēng)的名稱(chēng)空間中。你可以通過(guò)用名稱(chēng)空間顯式限定或包括如下語(yǔ)句從類(lèi)型庫(kù)頭部使用該名稱(chēng)。usingnamespaceMyLib在源代碼的#import語(yǔ)句之后立即名稱(chēng)空間可用#import指令的nonamespace屬性來(lái)阻止。但阻止的名稱(chēng)空間可能導(dǎo)致名稱(chēng)沖突。名稱(chēng)空間也可用renamenamespace屬性重新?lián)Q名。編譯器提供完全路徑給需要依賴(lài)當(dāng)前正在處理的類(lèi)型庫(kù)的任何類(lèi)型庫(kù)。路徑以注釋格式寫(xiě)入到由編譯器為每個(gè)處理的類(lèi)型庫(kù)生成的類(lèi)型庫(kù)頭部(.TLH)。如果ー個(gè)類(lèi)型庫(kù)包含了對(duì)其它類(lèi)型庫(kù)定義的類(lèi)型引用,.TLH文件將包括以下注釋:////Cross-referencedtypelibraries:H//#import"c:\path\typelibO.tlb"http://在#import注釋中的實(shí)際文件名是存儲(chǔ)在寄存器中交叉引用的類(lèi)型庫(kù)全路徑。如果你遇到由于省略類(lèi)型定義的錯(cuò)誤時(shí),檢查.TLH頭部的注釋,看哪ー種依賴(lài)類(lèi)型庫(kù)需要先輸入。在編譯該.TLI文件時(shí)可能的錯(cuò)誤有語(yǔ)法錯(cuò)誤(例如C2143,C2146,C2321)、C2501(缺少說(shuō)明指示符)或C2433(在數(shù)據(jù)說(shuō)明中禁止‘inline,)。你必須確定哪些依賴(lài)注釋是不被系統(tǒng)頭部給出的,而是在依賴(lài)類(lèi)型庫(kù)的#import指令前的某處給出ー個(gè)#import指令以消除這些錯(cuò)誤。exclude屬性exclude("稱(chēng)ド[,“名稱(chēng)2”,…])名稱(chēng)1被排斥的第一個(gè)項(xiàng)名稱(chēng)2被排斥的第二個(gè)項(xiàng)(如有必要)類(lèi)型庫(kù)可能包含在系統(tǒng)頭部或其它類(lèi)型庫(kù)內(nèi)定義的項(xiàng)的定義。該屬性可用于從生成的類(lèi)型庫(kù)頭文件中排斥這些項(xiàng)。這個(gè)屬性可帶任意數(shù)目的參量,每個(gè)參量是一個(gè)被排斥的高級(jí)類(lèi)型庫(kù)項(xiàng)目:highmethod_prefix屬性highmethod_prefix("Prefix")Prefix被使用的前綴在缺省的情況下,高級(jí)錯(cuò)誤處理屬性和方法用一個(gè)無(wú)前綴命名的成員函數(shù)來(lái)展示。這個(gè)名稱(chēng)來(lái)自于類(lèi)型庫(kù)。high_methodjprefix屬性說(shuō)明一個(gè)前綴以用于命名這些高級(jí)屬性和方法。high_property_prefixes屬性high_property_prefixes("GetPrefix,""PutPrefix,""PutRefPrefix")GetPrefix用于propget方法的前綴PutPrefix用于propput方法的前綴PutRefPrefix用于propputref方法的前綴在缺省情況下,高級(jí)錯(cuò)誤處理方法,如propget>propput和propputref,分別采用以前綴Get、Put和PutRef命名的成員函數(shù)來(lái)說(shuō)明。high_property_prefixes屬性用于分別說(shuō)明這三種屬性方法的前綴。implementation_only屬性implementationonly屬性禁止.TLH頭文件(基本頭文件)的生成。這個(gè)文件包括了所有用于展示類(lèi)型庫(kù)內(nèi)容的說(shuō)明。該.TLI頭文件和wrapper成員函數(shù)的實(shí)現(xiàn),將被生成且包含在編譯過(guò)程中。當(dāng)指定該屬性時(shí),該.TLI頭部的內(nèi)容將和用于存放普通.TLH頭部的內(nèi)容放在相同的名稱(chēng)空間。此外,該成員函數(shù)不會(huì)作為聯(lián)編說(shuō)明。implementationonly屬性一般希望與noimplementation屬性配對(duì)使用,以跟蹤預(yù)編譯頭文件(PCH)之外的實(shí)現(xiàn)。ー個(gè)有no_implementation屬性的#import語(yǔ)句被置于用來(lái)創(chuàng)建peh的源區(qū)域中,結(jié)果PCH將被ー些源文件所用。ー個(gè)帶implementation_only屬性的#import語(yǔ)句隨后被用在PCH區(qū)域之外。在一個(gè)源文件里只需用一次這種語(yǔ)句。這將生成不需對(duì)每個(gè)源文件進(jìn)行額外重編譯的所有必要的wrapper成員函數(shù)。注意:ー個(gè)#import語(yǔ)句中的implementation_only屬性必須和相同類(lèi)型庫(kù)中no_implementation屬性的另ー個(gè)#import語(yǔ)句配套使用。否則,將產(chǎn)生編譯錯(cuò)誤。這是因?yàn)閹oimplementation屬性的#import語(yǔ)句生成的wrapper類(lèi)定義需要編譯implementation_only屬性生成的語(yǔ)句實(shí)現(xiàn)。include^..)屬性Include(名稱(chēng)1[,名稱(chēng)2,…])名稱(chēng)1第一個(gè)被強(qiáng)制包含的項(xiàng)名稱(chēng)2第二個(gè)被強(qiáng)制包含的項(xiàng)(如果必要)類(lèi)型庫(kù)可能包含在系統(tǒng)頭部或其它類(lèi)型庫(kù)中定義的項(xiàng)的定義。#import指令試圖用自動(dòng)排斥這些項(xiàng)來(lái)避免多重定義錯(cuò)誤。若這些項(xiàng)已經(jīng)被排斥,象警告C4192所指出的那樣,且它們不應(yīng)該被排斥,則這個(gè)屬性可用于禁止自動(dòng)排斥。該屬性可帶任意數(shù)目的參量,每個(gè)參量應(yīng)是被包括的類(lèi)型庫(kù)項(xiàng)的名稱(chēng)。inject_statement屬性inject_statement("source_text")sourcetext被插入到類(lèi)型庫(kù)頭文件的源文本。inject_statement屬性將其參量作為源文本插入類(lèi)型庫(kù)頭部。此文本被置于包括頭文件中類(lèi)型庫(kù)內(nèi)容的名稱(chēng)空間說(shuō)明的起始處。named_guids屬性namedguids屬性讓編譯器定義和初始化模板LIBIDMyLib、CLSIDMyCoClass^IIDMyInterface和DIIDMyDispInterface的舊式格式的GUID變量。no_implementation屬性該屬性阻止.TLI頭文件的生成,這個(gè)文件包含wrapper成員函數(shù)的實(shí)現(xiàn)。如果指定這個(gè)屬性,則展示類(lèi)型庫(kù)項(xiàng)說(shuō)明的.TLH頭將生成沒(méi)有一個(gè)#include語(yǔ)句包括該.TLI頭文件。該屬性與implementation_only屬性配套使用。no_auto_exclude屬性類(lèi)型庫(kù)可能包括在系統(tǒng)頭部或其它類(lèi)型庫(kù)中定義的項(xiàng)的定義。#import試圖通過(guò)自動(dòng)排斥這些項(xiàng)來(lái)避免多重定義錯(cuò)誤。當(dāng)這樣做時(shí),每個(gè)被排斥的項(xiàng)都將生成一個(gè)C4192警告信息。你可禁止這個(gè)屬性使用自動(dòng)排斥。no_namespace屬性#import頭文件中的類(lèi)型庫(kù)內(nèi)容一般定義在ー個(gè)名稱(chēng)空間里。名稱(chēng)空間的名稱(chēng)在原來(lái)IDL文件的library語(yǔ)句中指定。如果指定no_namespace屬性,編譯器就不會(huì)生成這個(gè)名稱(chēng)空間。如果你想使用ー個(gè)不同的名稱(chēng)空間,應(yīng)代替使用rename_namespace屬性。raw_dispinterfaces丿禹性rawdispinterfaces屬性讓編譯器生成一個(gè)低級(jí)wr叩per函數(shù)。該函數(shù)用于調(diào)用IDispatch::Invoke和返回HRESULT錯(cuò)誤代碼的dispinterface方法和屬性。如果未指定此屬性,則只生成高級(jí)wrapper,它在失敗時(shí)丟棄該C++異常。raw_interfaces_only屬性raw_interfaces_only屬性禁止生成錯(cuò)誤處理wrapper函數(shù)以及使用這些wrapper函數(shù)的declspec(屬性)說(shuō)明。raw_interfaces_only屬性也導(dǎo)致刪除在命名non_property函數(shù)中的缺省前綴。通常該前綴是raw_。若指定此屬性,函數(shù)名稱(chēng)將直接從類(lèi)型庫(kù)中生成。該屬性只允許展示類(lèi)型庫(kù)的低級(jí)內(nèi)容。raw_method_prefix屬性raw_method_prefix("Prefix")Prefix被使用的前綴用raw_作為缺省前綴的成員函數(shù)展示低層屬性和方法,以避免與高級(jí)錯(cuò)誤處理成員函數(shù)的名稱(chēng)沖突。raw_method_prefix屬性用于指定一個(gè)不同的前綴。注意:raw_method_prefix屬性的效果不會(huì)因raw_method_prefix屬性的存在而改變。在說(shuō)明一"個(gè)前綴時(shí),raw_method_prefix總是優(yōu)先于raw_interfaces_only〇若兩種屬性用在同一個(gè)#import語(yǔ)句中時(shí),則采用raw_method_prefix指定的前綴。raw_native_types屬性在缺省情況下,高級(jí)錯(cuò)誤處理方法在BSTR和VARIANT數(shù)據(jù)類(lèi)型和原始COM界面指針的地方使用COM支持類(lèi)_bctr_t和一variant]。這些類(lèi)封裝了分配和取消分配這些數(shù)據(jù)類(lèi)型的存儲(chǔ)器存儲(chǔ)的細(xì)節(jié),并且極大地簡(jiǎn)化了類(lèi)型造型和轉(zhuǎn)換操作。raw_native_types屬性在高級(jí)wrapper函數(shù)中禁止使用這些COM支持類(lèi),并強(qiáng)制替換使用低級(jí)數(shù)據(jù)類(lèi)型。raw_property_prefix屬性raw_propertyprefix("GetPrefix","PutPrefix","PutRefPrefix")GetPrefix用于propget方法的前綴PutPrefix用于propput方法的前綴PutRefPrefix用于propputref方法的前綴在缺省情況下,低級(jí)方法propget、propput和propputref分別用后綴為get_>put_和putreし的成員函數(shù)來(lái)展示。這些前綴與MIDL生成的頭文件中的名稱(chēng)是兼容的。raw_property_prefixes屬性分別用于說(shuō)明這三個(gè)屬性方法的前綴。rename屬性rename("〇IdName,""NewName")OldName類(lèi)型庫(kù)中的舊名NewName用于替換舊名的名稱(chēng)rename屬性用于解決名稱(chēng)沖突的問(wèn)題。若該屬性被指定,編譯器將在類(lèi)型庫(kù)中的OldName的所有出現(xiàn)處用結(jié)果頭文件中用戶(hù)提供的NewName替換。此屬性用于類(lèi)型庫(kù)中的一個(gè)名稱(chēng)和系統(tǒng)頭文件中的宏定義重合時(shí)。若這種情況未被解決,則將產(chǎn)生大量語(yǔ)法錯(cuò)誤,如C2059和C2061o注意:這種替換用于類(lèi)型庫(kù)的名稱(chēng),而不是用于結(jié)果頭文件中的名稱(chēng)。這里有一個(gè)例子:假設(shè)類(lèi)型庫(kù)中有一個(gè)名稱(chēng)為MyParent的屬性,且頭文件中定義了一個(gè)用在#import之前的宏GetMyParent〇由于GetMyParent是用于錯(cuò)誤處理屬性get的ー個(gè)wrapper函數(shù)的缺省名稱(chēng),所以將產(chǎn)生一個(gè)名稱(chēng)沖突。為解決這個(gè)問(wèn)題,使用#imp〇rt語(yǔ)句中的以下屬性:rename("MyParent",''MyParentX")該語(yǔ)句將重新命名類(lèi)型庫(kù)中的名稱(chēng)MyParent,而試圖重新命名GetMyParentwrapper名稱(chēng)將會(huì)出錯(cuò):rename("GetMyParent","GetMyParentX")這是因?yàn)槊Q(chēng)GetMyParent只出現(xiàn)在結(jié)果類(lèi)型庫(kù)頭文件中。rename_namespace屬性rename_namespace("NewName")NewName名稱(chēng)空間的新名稱(chēng)renamenamespace屬性用于重新命名包含類(lèi)型庫(kù)內(nèi)容的名稱(chēng)空間。它帶有一個(gè)指定名稱(chēng)空間新名newname的參量。消除名稱(chēng)空間可以使用nonamespace屬性。C++特殊處結(jié)束#include指令include指令告訴預(yù)處理器處理一個(gè)指定文件的內(nèi)容,就象這些內(nèi)容以前就在這條指令出現(xiàn)的源程序中。你可以把常量和宏定義放在包含文件中,然后用#include指令把這些定義加到任何源文件中。包含文件對(duì)于外部變量和復(fù)雜數(shù)據(jù)類(lèi)型結(jié)合的說(shuō)明也是有用的。你只需在為此目的創(chuàng)建的ー個(gè)包含文件中定義和命名這些類(lèi)型ー次。語(yǔ)法#include"path-spec"#includepath_spec是ー個(gè)前面有目錄說(shuō)明的任選文件名。這個(gè)文件名必須命名ー個(gè)現(xiàn)存文件。path_spec的語(yǔ)法依賴(lài)于編譯該程序的操作系統(tǒng)。這兩種語(yǔ)法格式都導(dǎo)致用已說(shuō)明的包含文件的全部?jī)?nèi)容來(lái)替換該指令。兩種格式的區(qū)別在于路徑未完整指定時(shí)預(yù)處理器搜索頭文件的順序。語(yǔ)法格式動(dòng)作引號(hào)格式這種格式指示預(yù)處理器先在包含#include語(yǔ)句的文件的相同目錄內(nèi)搜索,然后在任何包括該文件的目錄中搜索。隨后預(yù)處理器沿著7!編譯器選項(xiàng)指定的路徑搜索,最后是在!NCLUDE環(huán)境變量說(shuō)明的路徑搜索尖括號(hào)格式這種格式指示預(yù)處理器首先在/1編譯器選項(xiàng)指定的路徑中搜索包含文件。然后在INCLUDE環(huán)境變量說(shuō)明的路徑中搜索一旦預(yù)處理器找到指定文件,它就立即停止搜索。如果用雙引號(hào)給出一個(gè)明確完整的包含文件的路徑,預(yù)處理器將只搜索該路徑規(guī)格而忽略標(biāo)準(zhǔn)目錄。如果在雙引號(hào)間的文件名不是ー個(gè)完整的路徑規(guī)格,預(yù)處理器將先搜索“父”文件的目錄。父文件是一個(gè)包含#include指令的文件。例如,如果你把名稱(chēng)為file2的文件包括在ー個(gè)名稱(chēng)為file!的文件中,filel就是父文件。包含文件可被嵌套;這指的是ー個(gè)#include指令出現(xiàn)在以另ー個(gè)#include指令命名的文件里。例如,以上的文件file2,可包含文件file3,在這種情況下,filel是file2的父文件,而且是file3的祖父文件。當(dāng)包含文件嵌套時(shí),目錄搜索首先由父文件的目錄開(kāi)始,然后,搜索祖父文件的目錄。因此,搜索從包含當(dāng)前處理源文件的目錄開(kāi)始,若文件未找到,搜索就轉(zhuǎn)到/I編譯器選項(xiàng)指定的目錄,最后搜索include環(huán)境變量指定的目錄。下面的例子給出使用尖括號(hào)的文件包括:#include這個(gè)例子把名稱(chēng)為STDIO.H的文件內(nèi)容加入到源程序中。尖括號(hào)指示預(yù)處理器在搜索完/1編譯器選項(xiàng)說(shuō)明的目錄之后,搜索STDIO.H的環(huán)境變量指定的目錄。下面的例子給出用引號(hào)格式的文件包括:#include"defs.h"這個(gè)例子把DEFS.H指定的文件內(nèi)容加入源程序。雙引號(hào)標(biāo)記意味著預(yù)處理器首先搜索包含父源文件的目錄。包含文件的嵌套可高達(dá)10層,只要在處理嵌套的#include指令時(shí),預(yù)處理器就會(huì)不斷地把包含文件加入到最初的源文件中。Microsoft特殊處為了定位可包括源文件,預(yù)處理器首先搜索/1編譯器選項(xiàng)指定的目錄。若/I選項(xiàng)未給定或已失敗,預(yù)處理器就用INCLUDE環(huán)境變量搜索尖括號(hào)內(nèi)的包含文件。INCLUDE環(huán)境變量和/1編譯器選項(xiàng)可包含用分號(hào)分開(kāi)的多個(gè)路徑。若在/1選項(xiàng)的部分或在INCLUDE環(huán)境變量里有多于ー個(gè)的目錄,預(yù)處理器將以它們出現(xiàn)的順序?qū)λ鼈冞M(jìn)行搜索。例如,命令:CL/ID:\MSVC\INCLUDEMYPROG.C導(dǎo)致預(yù)處理器在目錄D:\MSVC\INCLUDE中搜索諸如STDIO.H的包含文件。命令:SETINCLUDE=D:\MSVC\INCLUDECLMYPROG.C有相同的作用。如果所有搜索都失敗了,將產(chǎn)生一個(gè)致命編譯錯(cuò)誤。如果用包括ー個(gè)冒號(hào)的路徑(例如,F:\MSVC\SPECIAL\INCL\TEST.H)來(lái)完整地說(shuō)明一個(gè)包含文件的文件名,預(yù)處理器將沿此路徑搜索。對(duì)于指定為#include"path_spec"的包含文件,目錄搜索將從父文件的目錄開(kāi)始,然后搜索祖父文件的目錄。因此,搜索將從包含當(dāng)前處理的#include指令的源文件的目錄開(kāi)始,如果沒(méi)有祖父文件或文件未找到,搜索將繼續(xù),就像文件名包括在尖括號(hào)中一樣。Microsoft特殊處結(jié)束#line指令#line指令告訴預(yù)處理器將編譯器內(nèi)部存儲(chǔ)的行號(hào)和文件名轉(zhuǎn)變?yōu)橐粋€(gè)給定的行號(hào)和文件名。編譯器使用該行號(hào)和文件名指出編譯過(guò)程中發(fā)現(xiàn)的錯(cuò)誤。行號(hào)一般指的是當(dāng)前輸入行,文件名指當(dāng)前輸入文件。每處理一行,行號(hào)就增lo語(yǔ)法#line數(shù)字序列"文件名''opt數(shù)字序列的值可以是任何整型常數(shù)。宏替換可在預(yù)處理語(yǔ)言符號(hào)中執(zhí)行,但結(jié)果必須求值為正確的語(yǔ)法。文件名可以是任意字符的組合,且應(yīng)括在雙引號(hào)("“)間。如果省略文件名,則前面的文件名保持不變。你可以通過(guò)編寫(xiě)ー個(gè)#line指令來(lái)改動(dòng)源行號(hào)和文件名。翻譯器使用行號(hào)和文件名來(lái)確定預(yù)定義宏一FILE__和__LINE__的值。你可以使用這些宏把自描述錯(cuò)誤消息加入到程序文本中。有關(guān)這些宏的更多信息參見(jiàn)預(yù)定義的宏。_FILE__宏擴(kuò)展成內(nèi)容為用雙引號(hào)("")括起的文件名的ー個(gè)字符串。如果你改變行號(hào)和文件名,編譯器將忽略原有的值,用新值繼續(xù)處理。#line指令通常被程序生成器用來(lái)生成指向最初源程序的錯(cuò)誤消息,而不是生成程序。下面的例子用于說(shuō)明#line以及LINE和FILE宏。在這個(gè)語(yǔ)句中,內(nèi)部存儲(chǔ)的行號(hào)設(shè)置為151,文件名改為copy.co#line151"copy.c"在這個(gè)例子中,若一個(gè)給定的“斷言”(assertion)不為真,則宏ASSERT使用預(yù)定義宏_LINE__和__FILE__打印出一個(gè)關(guān)于源文件的錯(cuò)誤消息。#defineASSERT(cond)if(!(cond))\{prints"assertionerrorline%d,file(%s)\n",\_LINE__,__FILE_J;}Null指令空預(yù)處理器指令是一行中一個(gè)單獨(dú)的數(shù)字標(biāo)號(hào)片),無(wú)任何作用。語(yǔ)法#undef指令正如其名所隱含的,#undef指令取消(反定義)一個(gè)原來(lái)由#define指令創(chuàng)建的名稱(chēng)。語(yǔ)法#undef標(biāo)識(shí)符#undef指令取消標(biāo)識(shí)符的當(dāng)前定義。其結(jié)果是,標(biāo)識(shí)符的每次出現(xiàn)都將被預(yù)處理器所忽略。為取消ー個(gè)用#undef的宏定義,只須給出宏的標(biāo)識(shí)符,不須給出參數(shù)表。你也可以將#undef指令用于ー個(gè)原來(lái)未定義的標(biāo)識(shí)符。這將確認(rèn)這個(gè)標(biāo)識(shí)符是未定義的。宏替換不能在#undef語(yǔ)句中執(zhí)行。#undef指令通常和一個(gè)#define指令匹配,以在源程序中創(chuàng)建一個(gè)區(qū)域,在這個(gè)區(qū)域中一個(gè)標(biāo)識(shí)符有其特定的含義。例如,源程序的一個(gè)特有函數(shù)可以使用顯式常量定義不影響程序余下部分的環(huán)境特定值。#undef指令也可與#if指令配對(duì)以控制源程序的條件編譯過(guò)程。有關(guān)更多信息參見(jiàn)“#if、#elif>#else和#endif指令’‘〇下面的例子中,#undef指令取消了一個(gè)符號(hào)常量和一個(gè)宏的定義,注意該指令只給出了宏的標(biāo)識(shí)符。#defineWIDTH80#defineADD(X,Y)(X)+(Y)...#undefWIDTH#undefADDMicrosoft特殊處宏可通過(guò)采用/U選項(xiàng)的命令行反定義,此命令行后跟反定義的宏名稱(chēng)。此命令與在文件開(kāi)頭處的#undef宏名稱(chēng)語(yǔ)句序列的作用是相等的。Microsoft特殊處結(jié)束預(yù)處理器操作符#define指令的文本中有四種預(yù)處理器特有的操作符(它們的總結(jié)參見(jiàn)下面的表)。字符化、字符串化和語(yǔ)言符號(hào)粘貼操作符將在下面三章中討論。defined操作符的信息參見(jiàn)“#if、#elif、#else和#endif指令”。運(yùn)算符動(dòng)作字符串化操作符伊)將相應(yīng)實(shí)參置于雙引號(hào)內(nèi)字符化操作符併@)將相應(yīng)的參量置于單引號(hào)內(nèi),且將其作為字符處理(Microsoft特殊處)語(yǔ)言符號(hào)粘貼操作符(種)可將語(yǔ)言符號(hào)作為實(shí)參使用,且將其合并為其它的語(yǔ)言符號(hào)續(xù)表定義的操作符簡(jiǎn)化在某特定宏指令中復(fù)合表達(dá)式的寫(xiě)法字符串化操作符併)數(shù)字符號(hào)或“字符串化”操作符併)將宏參數(shù)(擴(kuò)展后)轉(zhuǎn)化為字符串常量。它只用于帶參量的宏。如果它在宏定義中的一個(gè)形式參量之前,宏調(diào)用傳給的實(shí)際參量就被括在雙括號(hào)中,且被看作為ー個(gè)字符串文字。然后該字符串文字將替換該宏定義中操作符和形參組合的每次出現(xiàn)。實(shí)參的第一個(gè)語(yǔ)言符號(hào)之前和最后ー個(gè)語(yǔ)言符號(hào)之后的空白被忽略。實(shí)參中語(yǔ)言符號(hào)之間的所有空白在結(jié)果字符串語(yǔ)義中都被看作為ー個(gè)空格。因此,若實(shí)參中的一個(gè)注解出現(xiàn)在兩個(gè)語(yǔ)言符號(hào)之間,它將被看作為一個(gè)空格。結(jié)果字符串文字自動(dòng)地與任何僅用空格分開(kāi)的相鄰字符串文字連接。此外,如果ー個(gè)包含在參量里的字符在用作一個(gè)字符串文字(例如,雙引號(hào)(つ或反斜杠。)字符)時(shí)通常需要一個(gè)轉(zhuǎn)義序列,必要的轉(zhuǎn)義反斜杠被自動(dòng)地插入字符之前。下面的例子給出了一個(gè)包含字符串化操作符的宏定義和一個(gè)調(diào)用該宏的main函數(shù):Sdefinestringer(x)printf(#x,\n")voidmain()stringer(Inquotesintheprintffunctioncall\n);stringer(z,Inquoteswhenprintedtothescreen"\n);stringer("This:ヽ“printsanescapeddoublequote");)這種調(diào)用在預(yù)處理時(shí)會(huì)被擴(kuò)展,產(chǎn)生如下代碼:voidmain(){printf(/zInquotesintheprintffunctioncall\n""\n");printf("\'Tnquoteswhenprintedtothescreen、'\n\n);printf("ヽ"This;\\\"printsanescapeddoublequote\"""\n");)當(dāng)運(yùn)行該程序時(shí),每行的屏幕輸出如下:Inquotesintheprintffunctioncall"Inquoteswhenprintedtothescreen""This;\"printsanescapeddoublequotationmark"Microsoft特殊處MicrosoftC(版本6.0及更早版本)擴(kuò)展ANSIC的標(biāo)準(zhǔn),ANSIC擴(kuò)展在字符串文字和字符常量中出現(xiàn)的宏形式參量不再被支持。依賴(lài)于此擴(kuò)展的代碼應(yīng)該使用字符串化操作符併)重寫(xiě)。Microsoft特殊處結(jié)束字符化操作符併@)Microsoft特殊處字符化操作符只可用于宏參量,若宏定義中#@在ー個(gè)形參前,則實(shí)參應(yīng)被放在單引號(hào)中,在宏擴(kuò)展時(shí)作為ー個(gè)字符處理。例如:#definemakechar(x)#@x將語(yǔ)句:a=makechar(b);擴(kuò)展為:a=rb';單引號(hào)字符不能用于字符化操作符。Microsoft特殊處結(jié)束語(yǔ)言符號(hào)粘貼操作符併#)雙數(shù)字語(yǔ)言符號(hào)或“語(yǔ)言符號(hào)粘貼”操作符(種),有時(shí)稱(chēng)作“合并‘‘操作符,用于類(lèi)對(duì)象宏和類(lèi)函數(shù)宏中。它允許將分開(kāi)的語(yǔ)言符號(hào)加入一個(gè)單個(gè)語(yǔ)言符號(hào)中,因此不能是宏定義的第一個(gè)語(yǔ)言符號(hào)或最后ー個(gè)語(yǔ)言符號(hào)。如果ー個(gè)宏定義中的形參在語(yǔ)言符號(hào)粘貼操作符的前后,則形參將立即被未擴(kuò)展的實(shí)參替換。在替換之前不對(duì)參量執(zhí)行宏擴(kuò)展。然后,語(yǔ)言符號(hào)字符串中語(yǔ)言符號(hào)粘貼操作符的每次出現(xiàn)將被刪除,其前后的語(yǔ)言符號(hào)將被合并。其結(jié)果語(yǔ)言符號(hào)必須是ー個(gè)有效的語(yǔ)言符號(hào)。若其有效,如果該語(yǔ)言符號(hào)代表ー個(gè)宏名稱(chēng),則掃描它以發(fā)現(xiàn)可能的替換。該標(biāo)識(shí)符表示在替換前程序中己知合并的語(yǔ)言符號(hào)的名稱(chēng)。每個(gè)語(yǔ)言符號(hào)都代表ー個(gè)在程序中或在編譯器命令行中定義的語(yǔ)言符號(hào)。該操作符前后的空白是任意的。如下例子說(shuō)明了程序輸出中字符串化操作符和語(yǔ)言符號(hào)粘貼操作符的用法:#definepaster(n)printf("token"#n"=%d",taken##n)inttoken9=9;若一個(gè)宏用ー個(gè)類(lèi)似于下面的數(shù)值參量調(diào)用:paster(9);宏將生成:printf("token""9""=%d",token9);它變成為:printf("token9=%d",token9);宏對(duì)宏擴(kuò)展的預(yù)處理在所有那些不是預(yù)處理指令的行(第一個(gè)非空白字符不是#的行),以及其指令并未作為條件編譯的一部分而忽略的行中進(jìn)行?!皸l件編譯’‘指令允許通過(guò)檢測(cè)ー個(gè)常量表達(dá)式或標(biāo)識(shí)符以決定在預(yù)處理過(guò)程中哪個(gè)文本塊送入編譯器、哪個(gè)文本塊從源文件中刪除,并以此種方式控制ー個(gè)源文件中某部分的編譯。#define指令通常使用有意義的標(biāo)識(shí)符與常量、關(guān)鍵字、常用語(yǔ)句和表達(dá)式關(guān)聯(lián)。表示常量的標(biāo)識(shí)符有時(shí)被稱(chēng)作“符號(hào)常量’’或"顯式’‘常量。表示語(yǔ)句或表達(dá)式的常量稱(chēng)為“宏'在本預(yù)處理器文檔中,只使用術(shù)語(yǔ)“宏'當(dāng)宏的名稱(chēng)在程序源文本或在某些其它預(yù)處理器命令的參量中被識(shí)別時(shí),它被處理為對(duì)該宏的調(diào)用。宏名稱(chēng)被宏體的ー個(gè)拷貝所替換。若該宏接受參量,宏名稱(chēng)后的實(shí)參就會(huì)替換宏體中的形參。用宏體中處理的拷貝來(lái)替換ー個(gè)宏調(diào)用的過(guò)程,稱(chēng)為宏調(diào)用的“擴(kuò)展”。實(shí)際的術(shù)語(yǔ)中有兩種類(lèi)型的宏?!邦?lèi)對(duì)象''宏不帶參量,而“類(lèi)函數(shù)”宏可定義為帶參量。因此它們的形式和功能都象函數(shù)調(diào)用,由于宏不生成實(shí)際的函數(shù)調(diào)用,所以有時(shí)可用宏替代函數(shù)調(diào)用使程序運(yùn)行得更快,(在C++中,inline函數(shù)通常是一個(gè)好方法),然而,如果不小心的定義和使用宏,也可能造成麻煩。在帶參量的宏定義時(shí),你必須使用括號(hào)以保持ー個(gè)表達(dá)式中正常的優(yōu)先級(jí),同時(shí)宏也不能正確地處理具有副作用的表達(dá)式。有關(guān)更多的信息參見(jiàn)“#define指令''中的例子getrandom。一旦你定義了一個(gè)宏,你不能不經(jīng)取消該宏原有定義,而重新定義它為ー個(gè)不同的值。但可用正好相同的定義來(lái)重定義該宏,因此,ー個(gè)程序中宏的相同定義可出現(xiàn)多次。#undef指令用于取消宏的定義。一旦取消該宏的定義,就可重新定義該宏為ー個(gè)不同的值。#define和#undef兩節(jié)分別詳細(xì)討論了#define和#undef指令。宏和C++C++提供了一些新的功能。其中有些功能替代了原來(lái)由ANSIC所提供的功能。這些新的功能增強(qiáng)了類(lèi)型安全性和該語(yǔ)言的可預(yù)測(cè)性:在C++中,以const說(shuō)明的對(duì)象可用于常量表達(dá)式中,這使程序說(shuō)明有類(lèi)型和值信息的常量,以及能被調(diào)試器逐個(gè)字符檢查的枚舉值的常量。使用預(yù)處理器指令#define定義常量并不精確。除非在程序中找到ー個(gè)帶地址的表達(dá)式,否則ー個(gè)const對(duì)象將不分配任何存儲(chǔ)。C++聯(lián)編函數(shù)替代了函數(shù)類(lèi)型宏,相對(duì)于宏來(lái)說(shuō)使用聯(lián)編函數(shù)的優(yōu)勢(shì)在于:類(lèi)型安全性。聯(lián)編函數(shù)和一般函數(shù)ー樣需進(jìn)行相同的類(lèi)型檢測(cè),宏無(wú)類(lèi)型安全性檢測(cè)。糾正具有副作用的參量處理。聯(lián)編函數(shù)在進(jìn)入函數(shù)體之前對(duì)參量的表達(dá)式求值。因此,ー個(gè)有副作用的表達(dá)式將是安全的。對(duì)于聯(lián)編函數(shù)的更多信息參見(jiàn)inline、__inline節(jié)。為了向下兼容,Micros。仕C++保留了所有在ANSIC和更早C++規(guī)格中的預(yù)處理器功能。預(yù)定義宏編譯器可識(shí)別六種預(yù)定義的ANSIC宏(參見(jiàn)表1.1),而MicrosoftC++實(shí)現(xiàn)提供更多的預(yù)定義宏(參見(jiàn)表1.2)。這些宏不帶參量,但不能被重定義。它們的值(除_LINE__和__FILE__外)必須是經(jīng)過(guò)編譯的常量。下面列出的一些預(yù)定義宏須用多個(gè)值來(lái)定義,它們的值可在VisualC++開(kāi)發(fā)環(huán)境中選擇相應(yīng)的菜單選項(xiàng)來(lái)設(shè)置或采用命令行開(kāi)關(guān)。更多的信息參見(jiàn)下表。表1.1ANSI預(yù)定義宏宏說(shuō)明_DATEー當(dāng)前源文件的編譯日期。日期是格式為Mmmddyyyy的字有串文字。月份名稱(chēng)Mmm與在TIME.H中說(shuō)明的庫(kù)函數(shù)asctime產(chǎn)生的日期ー樣_FILE__當(dāng)前源文件名稱(chēng)。_FILE_JT展為用雙引號(hào)括起的一個(gè)字符串_LINE當(dāng)前源文件的行號(hào)。該行號(hào)是一個(gè)十進(jìn)制整型常量??捎茅`個(gè)#line指令修改_STDC__指出與ANSIC標(biāo)準(zhǔn)的完全一?致性。僅當(dāng)給出/Za編譯器選項(xiàng)且不編譯C++代碼時(shí)定義為整型量1;否則是不確定的_TIME__當(dāng)前文件的最近編譯時(shí)間。該時(shí)間是格式為hh:mm:ss的字符串文字_TIMESTAMP_當(dāng)前源文件的最近修改日期。日期是格式為DddMmmDatehh:mm:ssyyyy的字符串文字,這里Ddd是星期兒的簡(jiǎn)寫(xiě),Date是從1到31的二個(gè)整數(shù)表表1.2Microsoft特殊預(yù)定義的宏宏說(shuō)明CHARUNSIGNED缺省char類(lèi)型是無(wú)符號(hào)的,當(dāng)指定/J時(shí)定義的cplusplus僅為C++程序定義CPPRTTI定義為用/GR編譯的代碼(允許運(yùn)行時(shí)類(lèi)型信息)CPPUNWIND定義為用/GX編譯的代碼(允許異常處理)DLL指定/MD或/MDd(多線(xiàn)程DLL)時(shí)定義的
_M_ALPHA為DECALPHA平臺(tái)定義,使用ALPHA編譯器時(shí)定義為1,若使用另ー個(gè)編譯器時(shí)不定義_M_IX86為x86處理器定義,參見(jiàn)表1.3_M_MPPC為PowerMacintosh平臺(tái)定義,缺省為601(/QP601)參見(jiàn)表1.4_M_MRXOOO為MIPS平臺(tái)定義,缺省為4000(/QMR400〇),參見(jiàn)表!,5_M_PPC為PowerPC平臺(tái)定義,缺省為604(/QP604),參見(jiàn)表1.6_MFC_VER為MFC版本定義,為MicrosoftFounndation類(lèi)庫(kù)4.21定義為0x0421,它總是定義的_MSC_EXTENSIONS該宏在使用/Ze編譯選項(xiàng)(缺省值)時(shí)定義,定義時(shí)其值總為1_MSC_VER定義編譯器版本,對(duì)于MicrosoftVisualC++6.0定義為1200,它總是定義的_MT當(dāng)指定/MD或/MDd(多線(xiàn)程DLL)或/MT或/MTd(多線(xiàn)程)選項(xiàng)時(shí)定義_WIN32為Win32應(yīng)用程序而定義。它總是定義的如下表所示,編譯器對(duì)反映處理器選項(xiàng)的預(yù)處理器標(biāo)識(shí)符產(chǎn)生一個(gè)值。表1.3_M_IX86的值開(kāi)發(fā)者的選項(xiàng)命令行選項(xiàng)返冋值Blend/GB_M」X86=500(缺省值。將來(lái)的編譯器將給出ー個(gè)不同的值以影響主處理器)Pentium/G5M1X86=500Pentiumpro/G6M1X86=60080386/G3M1X86=30080486/G4_M_IX86=400表1.4_M_MPPC的值開(kāi)發(fā)者的選項(xiàng)命令行選項(xiàng)返回值PowerPC601/QP601_M_MPPC=601(缺省值)PowerPC603/QP603_M_MPPC=603PowerPC604/QP604_M_MPPC=604
PowerPC620|/QP620|MMPPC=620PowerPC620|/QP620|MMPPC=620表!.5MMRX000的值開(kāi)發(fā)者選項(xiàng)命令行選項(xiàng)返回值R4000/QMR4000_M_MRX000=4000(缺省值)R4100/QMR4100_M_MRX000=4100R4200/QMR4200_M_MRX000=4200R4400/QMR4400_M_MRX000=4400R4600/QMR4600_M_MRX000=4600R10000/QMR10000_M_MRX000=10000表!.6_M_PPC的值開(kāi)發(fā)者選項(xiàng)命令行選項(xiàng)返回值R4000/QMR4000_M_MRX000=4000(缺省值)R4100/QMR4100_M_MRX000=4100R4200/QMR4200_M_MRX000=4200R4400/QMR4400_M_MRX000=4400R4600/QMR4600_M_MRX000=4600RI0000/QMR10000_M_MRX000=10000編譯指示指令C++編譯器專(zhuān)有編譯指示C和C++的每個(gè)實(shí)現(xiàn)對(duì)它的主機(jī)或操作系統(tǒng)都支持ー些獨(dú)有的特征。例如,某些程序須對(duì)存放數(shù)據(jù)的存儲(chǔ)器區(qū)域進(jìn)行精確的控制,或必須控制特定函數(shù)接受參量的方式。#pragma指令對(duì)每個(gè)編譯器給出了一個(gè)方法,在保持與C和C++語(yǔ)言完全兼容的情況下,給出主機(jī)或操作系統(tǒng)專(zhuān)有的特征。依據(jù)定義,編譯指示是機(jī)器或操作系統(tǒng)專(zhuān)有的,且對(duì)于每個(gè)編譯器都是不同的。語(yǔ)法#pragma語(yǔ)言符號(hào)字符串語(yǔ)言符號(hào)字符串是給出特有編譯器指令和參量的字符序列。數(shù)字符號(hào)(#)必須是包含編譯指示行中的第一個(gè)非空白字符??瞻鬃址煞珠_(kāi)數(shù)字符號(hào)(#)和單詞pragma。在#pragma之后,可以編寫(xiě)翻譯器作為預(yù)處理器語(yǔ)言符號(hào)分析的任何文本。#pragma的參量從屬于宏擴(kuò)展。如果編譯器找到ー個(gè)不能識(shí)別的編譯指示,將發(fā)出一個(gè)警告,但編譯將繼續(xù)。編譯指示可用在條件說(shuō)明中,以提供新的預(yù)處理器功能,或提供定義的實(shí)現(xiàn)信息給編譯器。C和C++編譯器可識(shí)別下面的編譯指示:alloc_textcommentinitseg*optimizeautoinlinecomponentinlinedepthpackbss_segdataseginlinerecursionpointers_tomembers*checkstackfunctionintrinsicsetlocalecode_seghdrstopmessagevtordisp*constsegincludealiasoncewarning*僅被C++編譯器支持C++編譯器專(zhuān)有編譯指示以下是C++編譯器專(zhuān)有的編譯指示指令:initseglpointerstomembersvtordispinit_segC++特殊處#pragmainit-seg({complier/lib/user/"section-name"輸nc-name"[})該扌旨令指定一個(gè)影響啟動(dòng)代碼執(zhí)行順序的關(guān)鍵字或代碼段。由于全局靜態(tài)對(duì)象的初始化可能涉及執(zhí)行代碼,因此必須指定創(chuàng)建對(duì)象時(shí)定義的ー個(gè)關(guān)鍵字。在動(dòng)態(tài)連接庫(kù)(DLL)或需初始化的庫(kù)中使用init_seg編譯指示尤其重要。initseg編譯指示的選項(xiàng)如下:compiler該選項(xiàng)保留給MicrosoftC運(yùn)行庫(kù)初始化。這個(gè)組中的對(duì)象最先被創(chuàng)建。lib用于第三方類(lèi)庫(kù)供應(yīng)商的初始化。該組中的對(duì)象在complier標(biāo)志之后,其他標(biāo)記之前創(chuàng)建。user用于任何用戶(hù)。此組對(duì)象最后創(chuàng)建。sectionname允許初始化段的顯示規(guī)格。在ー個(gè)用戶(hù)指定section-name(段名稱(chēng))中的對(duì)象不能被隱含地創(chuàng)建,但它們的地址可放在以sectionname命名的段中。func_name指定在程序退出時(shí)在exit。地方調(diào)用的函數(shù)。指定的函數(shù)必須與exit函數(shù)具有相同的特征:intfuncname(void(_cdecl*)(void));如果你需要延遲初始化過(guò)程(例如,在ー個(gè)DLL中),你可以選擇顯式地指定該段名稱(chēng)。然后必須為每個(gè)靜態(tài)對(duì)象調(diào)用構(gòu)造函數(shù)。C++特殊處結(jié)束pointers_to_membersC++特殊處#progmapointersto_members(指針說(shuō)明」最一般表示])該指令指定一個(gè)類(lèi)成員的指針能否在其相關(guān)定義之前被說(shuō)明,且用于控制該指針尺寸和解釋該指針需要的代碼。你可以把ー個(gè)pointerstomembers編譯指示放入你的源文件中替換/vmx編譯器選項(xiàng)。指針說(shuō)明參量指定你在ー個(gè)關(guān)聯(lián)函數(shù)定義之前還是之后說(shuō)明了一個(gè)成員的指針。指針說(shuō)明參量是以下兩個(gè)符號(hào)之一:參量時(shí)明生成安全、但常常并非最優(yōu)的代碼。如果在關(guān)聯(lián)類(lèi)定義之前說(shuō)明fullgenerality任何成員的指針,可使用fullgeneralityo該參量通常使用最?般表示參量指定的指針表示形式。等同于/vmg選項(xiàng)best_case為所有成員指針使用最佳情況(best_case)表示生成安全的最優(yōu)代碼。使用該參量是需在定義ー個(gè)類(lèi)的成員指針說(shuō)明之前定義此類(lèi)。其缺省值為bestcasebestcase為所有成員指針使用最佳情況(best_case)表示生成安全的最優(yōu)代碼。使用該參量是需在定義ー個(gè)類(lèi)的成員指針說(shuō)明之前定義此類(lèi)。其缺省值為best_case最一般表示參量說(shuō)明了在轉(zhuǎn)換單元中,編譯器能夠安全地引用任何指向類(lèi)成員的指針的最小指針表示。該參量取如下值之一:參量說(shuō)明single_inheritance最ー一般表示是單繼承的,即ー個(gè)成員函數(shù)的指針。對(duì)于其中說(shuō)明了一個(gè)指向成員指針的ー個(gè)類(lèi)定義,若其繼承模式說(shuō)明為多重的或虛擬的,將導(dǎo)致錯(cuò)誤multiple_inheritance最一般表示是多重繼承的,即ー個(gè)成員函數(shù)的指針。對(duì)于其中說(shuō)明了一個(gè)指向成員指針的ー個(gè)類(lèi)定義,若其繼承模式是虛擬的,將導(dǎo)致錯(cuò)誤vitualinheritance最一般表示是虛擬繼承,即ー個(gè)成員函數(shù)的指針。該函數(shù)不會(huì)導(dǎo)致錯(cuò)誤。當(dāng)使用#pragmapointers_to_members(full_generality)時(shí)這是個(gè)缺省參量C++特殊處結(jié)束vtordispC++特殊處#pragmavtordisp({on|off})該指令允許增加隱含的vtordisp構(gòu)造函數(shù)/析構(gòu)函數(shù)替換成員。vtordisp編譯指示只使用虛基類(lèi)的代碼。若一個(gè)派生類(lèi)重迭ー個(gè)從虛擬基類(lèi)繼承的虛擬函數(shù),且如果派生類(lèi)的一個(gè)構(gòu)造函數(shù)或析構(gòu)函數(shù)調(diào)用那個(gè)使用該虛擬基類(lèi)指針的函數(shù),則編譯器可能將增加的隱含“vtordisp”域到有虛擬基的類(lèi)中。vtordisp編譯指示會(huì)影響其后類(lèi)的分布。/VdO或”dl選項(xiàng)指定了對(duì)于完全模式的相同動(dòng)作。指定off將抑制隱含的vtordisp成員。指定缺省值on,將在需要的位置打開(kāi)它們。Vtordisp指令僅在類(lèi)的構(gòu)造/析構(gòu)函數(shù)在用this指針指向的對(duì)象處不可能調(diào)用虛擬函數(shù)時(shí)關(guān)閉。#pragmavtordisp(off)classGetReal:virtualpublic{...};#pragmavtordisp(on)C++特殊處結(jié)束C和C++編譯器編譯指示以下是為C和C++編譯器定義的編譯指示:alloctextcomponentinitseg*optimizeautoinlineconstseginlinedepthpackbss_segdata_seginline_recursionpointers_tomembers*checkstackfunctionintrinsicsetlocalecode_seghdrstopmessagevtordisp*commentinclude_aliasoncewarning僅被C++編譯器支持alloc_text#pragmaallojtext(“文本段”,函數(shù)1,...)該指令用于命名指定的函數(shù)定義將要駐留的代碼段。該編譯指示對(duì)已命名的函數(shù)必須出現(xiàn)在ー個(gè)函數(shù)說(shuō)明符和該函數(shù)定義之間。alloctjext編譯指示并不處理C++成員函數(shù)或重載函數(shù)。它僅用于以C連接方式說(shuō)明的函數(shù),這指的是用extern“C”連接規(guī)格說(shuō)明的函數(shù)。如果你試圖將此編譯指示用于非C++連接的函數(shù),將產(chǎn)生一個(gè)編譯錯(cuò)誤。由于不支持使用—based的函數(shù)地址,指定段位址需要使用allocjext編譯指示,以文本段指定的名稱(chēng)應(yīng)包括在雙引號(hào)間。alloctext編譯指示必須出現(xiàn)在指定的函數(shù)說(shuō)明之后,這些函數(shù)的定義之前。ー個(gè)allocjext編譯指示中的函數(shù)引用必須在此編譯指示的同一模塊中定義。如果未這樣做,且ー個(gè)未定義的函數(shù)隨后被編譯到ー個(gè)不同的文本段,則這個(gè)錯(cuò)誤可能找得到,也可能找不到。雖然該程序一般會(huì)正常運(yùn)行,但該函數(shù)不會(huì)分配到預(yù)期的段中。alloctext的其他限制如下:?它不能用在ー個(gè)函數(shù)的內(nèi)部。?它必須在已說(shuō)明的函數(shù)之后和已定義的函數(shù)之前使用。auto_mline#pragmaauto_inline([{on|off}])排除自動(dòng)內(nèi)聯(lián)擴(kuò)展的候選者中指定為off的區(qū)域中定義的函數(shù)。為了使用auto_inline編譯指示,把它放在ー個(gè)函數(shù)定義之前或立即之后(不在該函數(shù)定義之內(nèi))。在看到該編譯指示之后的第一個(gè)函數(shù)定義處,該編譯指示發(fā)生作用。編譯指示auto_inline不能應(yīng)用于顯式內(nèi)聯(lián)函數(shù)。bss_seg#pragmadata-seg(["section-name"[,"section-class"]])指定未初始化數(shù)據(jù)的缺省段。data_seg編譯指示處理初始化或未初始化數(shù)據(jù)有相同的作用。在某些情況下,你可以使用bss_seg通過(guò)把所有未初始化數(shù)據(jù)放在ー個(gè)段中來(lái)加速加載的時(shí)間。#pragmabssseg("MYDATA")導(dǎo)致#pragma語(yǔ)句后未初始化的數(shù)據(jù)分配到ー個(gè)名稱(chēng)為MY_DATA的段中。用bss_seg編譯指示分配的數(shù)據(jù)不會(huì)保留關(guān)于它的位置的任何信息。第二個(gè)參量section_class用于與VisualC++之前的版本兼容,現(xiàn)在已被忽略。check_stack#pragmacheck_stack([{on|off}])#pragmacheck_stack{+|-}該指令在off(或-)選項(xiàng)時(shí)指示編譯器關(guān)閉棧搜索。在on(或+)選項(xiàng)指定時(shí),打開(kāi)搜索。若無(wú)參量,棧搜索就按缺省情況處理。在看到該編譯指示之后第一個(gè)定義的函數(shù)處發(fā)生作用。棧搜索既不是宏的一部分,也不是產(chǎn)生的內(nèi)聯(lián)函數(shù)的一部分。如果未賦予ー個(gè)參量給check_stack編譯指示,棧檢查將還原成在命令行中說(shuō)明的行為,有關(guān)更多的信息參見(jiàn)“編譯器參考“。#pragmacheck_stack和/Gs選項(xiàng)的交互關(guān)系參見(jiàn)表2.1〇表2.1使用check_stack編譯指示語(yǔ)法是否用/Gs選項(xiàng)編譯行為#pragmacheck_stack()或#pragmacheck_stack是關(guān)閉其后函數(shù)的棧檢查#pragmacheck_stack()或#pragmacheckstack否打開(kāi)其后函數(shù)的棧檢查#pragmacheckstack(on)或#pragmacheck_stack+是或否打開(kāi)其后函數(shù)的棧檢查#pragmacheckstack(off)或#pragmacheck_stack-是或否關(guān)閉其后函數(shù)的棧檢查code_seg#pragmacode_seg(["section-name"[,"section-class"]])該指令用于指定一個(gè)分配函數(shù)的代碼段。code_seg編譯指示指定了函數(shù)的缺省段。你可以有選擇性地指定類(lèi)和段名。使用沒(méi)有section-name字符串的#pragmacode_seg可在編譯開(kāi)始時(shí)將其復(fù)位。const_seg#pragmaconst_seg(["section-name"[,"section-class"]])該指令用于指定對(duì)于常量數(shù)據(jù)的缺省段。data_seg編譯指示對(duì)所有數(shù)據(jù)具有相同作用。你可以用此指令將你的所有常量數(shù)據(jù)放入一個(gè)只讀段中。#pragmaconstseg("MYDATA")導(dǎo)致該指令將#pragma語(yǔ)句后的常量數(shù)據(jù)放入ー個(gè)名稱(chēng)為MYDATA的段里。使用const_seg編譯指示分配的數(shù)據(jù)不會(huì)保留有關(guān)它的位置的任何信息。第二個(gè)參數(shù)section-class用于與VisualC++2.0版之前的版本兼容,現(xiàn)在已可忽略。comment#pragmacomment(comment-type,[commentstring])該指令將一個(gè)注釋記錄放入ー個(gè)對(duì)象文件或可執(zhí)行文件中。comment-type是下面五種說(shuō)明的預(yù)定義標(biāo)識(shí)符之一,它們指出了注釋記錄的類(lèi)型。任選的commentstring是給ー些注釋類(lèi)型提供額外信息的字符串文字。由于commentstring是ー個(gè)字符串文字,因此它必須遵循對(duì)于字符串文字的諸如轉(zhuǎn)義字符、嵌入或引號(hào)標(biāo)記(ッ以及合并的所有規(guī)則。compiler該選項(xiàng)將編譯器的名稱(chēng)和版本號(hào)放入對(duì)象文件中。這個(gè)注釋記錄被鏈接器忽略,如果你為這個(gè)記錄類(lèi)型給出ー個(gè)commentstring參量,該編譯器將產(chǎn)生一個(gè)警告信息。exestr該選項(xiàng)將commentstring放入對(duì)象文件中。在連接時(shí),該字符串被置入可執(zhí)行文件中。該字符串并不與可執(zhí)行文件同時(shí)加載到存儲(chǔ)器,但它可用在文件中尋找可打印字符串的程序找到。這個(gè)注釋記錄類(lèi)型的ー個(gè)用途是把版本號(hào)或類(lèi)似信息嵌入到ー個(gè)可執(zhí)行文件中。lib該選項(xiàng)將一個(gè)庫(kù)搜索記錄放入對(duì)象文件。該注釋類(lèi)型必須帶有一個(gè)commentstring參數(shù)。這個(gè)參數(shù)包含你想要的鏈接器搜索的庫(kù)的名稱(chēng)(有可能包含路徑)。由于在對(duì)象文件中該庫(kù)名稱(chēng)在缺省的庫(kù)搜索記錄之前,所以鏈接器搜索該庫(kù)就象你在命令行中命名了它ー樣。你可以把多個(gè)庫(kù)搜索記錄放在同一個(gè)源文件中,每個(gè)記錄在對(duì)象文件中都以其在
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- DB6528T 140-2024庫(kù)爾勒香梨密植高效栽培技術(shù)規(guī)程
- 五年期產(chǎn)品供應(yīng)合同書(shū)
- 個(gè)人住房融資合同協(xié)議書(shū)
- 人事保管檔案合同實(shí)施細(xì)則
- 個(gè)人養(yǎng)殖場(chǎng)合作協(xié)議合同
- 個(gè)人合伙合作協(xié)議書(shū)合同范本
- 個(gè)人借款合同延期至協(xié)議
- 產(chǎn)品銷(xiāo)售補(bǔ)償合同范本
- 買(mǎi)賣(mài)合同糾紛起訴書(shū)范本
- XX市小學(xué)結(jié)對(duì)合作合同
- cpk自動(dòng)計(jì)算電子表格表格
- 2024-2025學(xué)年湖北省武漢市部分重點(diǎn)中學(xué)高一上學(xué)期期末聯(lián)考數(shù)學(xué)試卷(含答案)
- 排球正面上手傳球 說(shuō)課稿-2023-2024學(xué)年高一上學(xué)期體育與健康人教版必修第一冊(cè)
- 2025年浙江省交通投資集團(tuán)財(cái)務(wù)共享服務(wù)中心招聘2名高頻重點(diǎn)提升(共500題)附帶答案詳解
- 做投標(biāo)文件培訓(xùn)
- 9.4+跨學(xué)科實(shí)踐:制作簡(jiǎn)易活塞式抽水機(jī)課件+-2024-2025學(xué)年人教版物理八年級(jí)下冊(cè)
- 建筑工程工作計(jì)劃
- 2025年中國(guó)國(guó)際投資促進(jìn)中心限責(zé)任公司招聘管理單位筆試遴選500模擬題附帶答案詳解
- 瓶裝液化氣送氣工培訓(xùn)
- 外科護(hù)理課程思政課程標(biāo)準(zhǔn)
- 船舶航行安全
評(píng)論
0/150
提交評(píng)論