2013-04-26 19 views
0

剛剛抓到一個愚蠢的錯誤。我有一個帶有CreateFile()函數的zip處理庫。 Winbase.h,包含在我的頭文件深處,將其重新定義爲CreateFileW並且鏈接器變得瘋狂。如何在本地禁止#define?

當然在這種情況下我會排除winbase。它不應該在第一位的範圍內。但理論問題仍然有趣,

有沒有辦法抑制一些本地定義?

回答

2

刪除有問題的頭文件始終是最好的解決方案(尤其是一個大到windows.hwinbase.h - 它們被包括在太多,我不喜歡在許多項目中)。

唯一的其他解決方案是#undef offending_symbol

當然,另一個重要的是「不要使用與Windows/Linux系統調用名稱匹配的名稱」 - 但是CreateFile是創建文件的函數的一個非常明顯的名稱,所以我可以看到誘惑。

+1

「不要使用名稱......」可能很難完成,因爲認真對待它應該是「不要使用與OS API調用匹配的名稱,也不要使用與其他常用API調用的名稱匹配的名稱,在某一天成爲API調用...「;-)更好地堅持」只在你的代碼的一小部分內容中使用第三方API「。 – 2013-04-26 13:52:40

+0

是的,我同意你評論的兩個方面。一些API名稱也非常通用,因此很難避免與它們發生衝突......並且將與系統相關的代碼粘貼到單獨的源文件中肯定是一個好主意 - 也可以移植到不同的操作系統(或不同的第三方庫,等)更簡單。 – 2013-04-26 13:59:59

1

#undef 

這消除定義(但沒有別的)。

2

預處理器宏沒有C++範圍的概念。 #define s只是文本替換。如果你想有一個「本地」 #define,你做這樣的事情:

#define CreateFileW CreateFile 
... // here I can use the macro 
#undef CreateFileW 

或者在你的情況

#undef CreateFileW 
... // Here the macro is not available 
#define CreateFileW CreateFile 
1

除了上述#undef有技術上沒有什麼可以做對抗#define s,至少不會移植。

最好的方法是根本不使用#define,或者儘可能少或儘可能少。有時候你只需要一個宏來幾次生成一些樣板代碼。一旦完成,請務必使用#undef宏。 #define我能想到的唯一其他有效應用包括用於條件預處理的警衛和標誌。

對於#define-類似於WinAPI頭的問題,您應該儘可能限制它們。請勿在標題中使用該API的#define d類型。您幾乎從不想在整個應用程序中使用API​​,因此只能在API周圍的小圖層的cpps中使用它。減少這種方式的依賴性不僅僅是消除代碼的其餘部分。

4

你可以將周圍的名字括號繞過宏:

(CreateFile)(arguments); 

這工作,因爲宏觀CreateFile是一個函數宏(即它需要的參數在括號中的列表);名稱後的右括號與使用類似函數的宏的語法不匹配,所以預處理器不會擴展它。

當然,「正確」的解決方案是正確命名功能,即,create_file<g>

+0

I'<‍g‍>''ed。 – Potatoswatter 2013-05-30 09:49:42