其他先行編譯指令
除了上面我們說的集中常用的編譯指令,還有3種不太常見的編譯指令:#line、#error、#pragma,我們接下來就簡單的談一下。
#line的文法如下:
#line number filename
例如:#line 30 a.h 其中,檔案名稱a.h可以省略不寫。
這條指令可以改變當前的行號和檔案名稱,例如上面的這條預先處理指令就可以改變當前的行號為30,檔案名稱是a.h。初看起來似乎沒有什麼用,不過,他還是有點用的,那就是用在編譯器的編寫中,我們知道編譯器對C++源碼編譯過程中會產生一些中間檔案,通過這條指令,可以保證檔案名稱是固定的,不會被這些中間檔案代替,有利於進行分析。
#error文法如下:
#error info
例如:#ifndef UNIX
#error This software requires the UNIX OS.
#endif
這條指令主要是給出錯誤資訊,上面的這個例子就是,如果沒有在UNIX環境下,就會輸出This software requires the UNIX OS.然後誘發編譯器終止。所以總的來說,這條指令的目的就是在程式崩潰之前能夠給出一定的資訊。
至於#pragma,我們在《解析#pragma指令 》一文中有過介紹,我們在這裡再補充幾句,#pragma是非統一的,他要依靠各個編譯器生產者,例如,在SUN C++編譯器中:
// 把name和val的起始地址調整為8個位元組的倍數
#progma align 8 (name, val)
char name[9];
double val;
file://在程式執行開始,調用函數MyFunction
#progma init (MyFunction)
預定義標識符
為了處理一些有用的資訊,預先處理定義了一些預先處理標識符,雖然各種編譯器的預先處理標識符不盡相同,但是他們都會處理下面的4種:
__FILE__ 正在編譯的檔案的名字
__LINE__ 正在編譯的檔案的行號
__DATE__ 編譯時間刻的日期文字,例如: "25 Dec 2000"
__TIME__ 編譯時間刻的時間字串,例如: "12:30:55"
例如:cout<<"The file is :"<<__FILE__"<<"! The lines is:"<<__LINE__<<endl;
預先處理何去何從
在《淺析C++裡面的宏》一文中,我們提到了如何取代#include預先處理指令,我們在這裡就不再一一討論了。
C++並沒有為#include提供替代形式,但是namespace提供了一種範圍機制,它能以某種方式支援組合,利用它可以改善#include的行為方式,但是我們還是無法取代#include。
#progma應該算是一個可有可無的預先處理指令,按照C++之父Bjarne的話說,就是:“#progma被過分的經常的用於將語言語義的變形隱藏到編譯系統裡,或者被用於提供帶有特殊語義和笨拙文法的語言擴充。”
對於#ifdef,我們仍然束手無策,就算是我們利用if語句和常量運算式,仍然不足以替代她,因為一個if語句的本文必須在文法上正確,滿足類檢查,即使他處在一個絕不會被執行的分支裡面。
最後,我們以Bjarne博士的話作為結尾:“最後---在許多年之後---將Cpp放逐刀程式開發環境裡,與其它附加性語言工具放到一起,那裡才是她應該呆的地方。”