2016-08-24 70 views
0

我正在爲Windows,Unix和Mac製作跨平臺程序。爲了能夠使用特定於每個操作系統的東西,我使用#define,例如,在編譯Windows時,我使用#define WINDOWS。爲了確保不定義不存在的OS,或者至少是我的程序不支持,我用這個:在特定行處發生預處理器錯誤

#ifndef WINDOWS 
#ifndef UNIX 
#ifndef MAC 
#error "OS must be WINDOWS, UNIX or MAC" 
#endif 
#endif 
#endif 

當我定義一個無效的OS,是給我一個錯誤,因爲它應該,但它會將紅色的矩形表示錯誤在#error行之前。我想把它放在我定義操作系統的那一行的前面。例如,如果我應該在第11行定義操作系統,我希望它將我發送到第11行。有沒有辦法做到這一點?

+0

如何在第11行定義操作系統?只用(例如)#define WINDOWS?如果 – vadikrobot

+0

@vadikrobot我在第11行定義操作系統意味着我的程序中的第11行包含例如'#define WINDOWS'。 –

+0

如果此行不存在,您希望在此行上看​​到錯誤? – vadikrobot

回答

3

如果你想顯示具體的行一個錯誤,如果有你的代碼中沒有定義的宏,嘗試使用#行

1 #ifndef UNIX 
2 #ifndef MAC 
3 #line 11 
4 #error "OS must be WINDOWS, UNIX or MAC" 
5 #endif 
6 #endif 
7 #endif 
8  
9 int main() 
10 { 
11 // here will be error from line 4 
12 } 
2

預處理器非常簡單。您在此處唯一的選項是在錯誤消息中包含行號。因爲如果#define這個數字在其他地方,你怎麼能確定這個#define甚至被處理,因爲這種情況會遺漏其他定義(你正在檢查的操作系統)。另外,你不可能在同一個行號上定義所有的三個宏,除非你對這些東西都有單獨的頭文件,這看起來像一個非常脆弱的系統。底線是你無法弄清楚什麼地方應該被定義,如果它從來沒有被定義在第一位。

如果這是純粹的C++,有更好的方法來處理這個比定義。我們想到了constexprstatic_assert,使用像Boost.Predef這樣的標準設施似乎比手動定義這些東西更好。

0

你也許可以做你想做什麼(什麼可以保證)但如果你改變你的邏輯。

C預處理器不知道哪個宏命名了一個操作系統和哪些名稱是別的。沒有辦法捕捉到你認爲某個操作系統不是你能處理的三個操作系統的宏。代替許多可能的宏名稱,請使用一個具有許多可能值的宏。現在當你看到你無法處理的價值時,你可能會做些事情。

#define WINDOWS 1002437 // a random magic number 
#define UNIX 2753321 
... 

#define OS UNIX 

... 

#if OS == WINDOWS 
    ... 
#elseif OS == UNIX 
    ... 
#elseif ... 
    ... 
#else // here comes the trick 
    #define OS 99997321 
    #error "Bad OS" 
#endif 

如果宏定義,許多編譯器會警告你重新定義它,並說正是第一個定義可以被發現。然而,這並不能保證。

當然,如果操作系統從未定義過,甚至沒有理論上的可能性來查明定義的而不是的位置。如果你知道它應該定義在那裏,你可以使用__LINE____FILE__指令編譯器引導到那個地方:

#line 11 
    #error "OS should be defined here" 

在真正的軟件然而,這樣的宏由編譯器命令行通常定義,並受控通過你的makefile或等價物。

CPPFLAGS += "-DOS=$(OS_ID)" 

所以在源代碼中沒有可以歸咎於錯誤的地方。