剛剛抓到一個愚蠢的錯誤。我有一個帶有CreateFile()
函數的zip處理庫。 Winbase.h
,包含在我的頭文件深處,將其重新定義爲CreateFileW
並且鏈接器變得瘋狂。如何在本地禁止#define?
當然在這種情況下我會排除winbase
。它不應該在第一位的範圍內。但理論問題仍然有趣,
有沒有辦法抑制一些本地定義?
剛剛抓到一個愚蠢的錯誤。我有一個帶有CreateFile()
函數的zip處理庫。 Winbase.h
,包含在我的頭文件深處,將其重新定義爲CreateFileW
並且鏈接器變得瘋狂。如何在本地禁止#define?
當然在這種情況下我會排除winbase
。它不應該在第一位的範圍內。但理論問題仍然有趣,
有沒有辦法抑制一些本地定義?
刪除有問題的頭文件始終是最好的解決方案(尤其是一個大到windows.h
或winbase.h
- 它們被包括在太多,我不喜歡在許多項目中)。
唯一的其他解決方案是#undef offending_symbol
。
當然,另一個重要的是「不要使用與Windows/Linux系統調用名稱匹配的名稱」 - 但是CreateFile
是創建文件的函數的一個非常明顯的名稱,所以我可以看到誘惑。
有
#undef
這消除定義(但沒有別的)。
預處理器宏沒有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
除了上述#undef
有技術上沒有什麼可以做對抗#define
s,至少不會移植。
最好的方法是根本不使用#define
,或者儘可能少或儘可能少。有時候你只需要一個宏來幾次生成一些樣板代碼。一旦完成,請務必使用#undef
宏。 #define
我能想到的唯一其他有效應用包括用於條件預處理的警衛和標誌。
對於#define
-類似於WinAPI頭的問題,您應該儘可能限制它們。請勿在標題中使用該API的#define
d類型。您幾乎從不想在整個應用程序中使用API,因此只能在API周圍的小圖層的cpps中使用它。減少這種方式的依賴性不僅僅是消除代碼的其餘部分。
你可以將周圍的名字括號繞過宏:
(CreateFile)(arguments);
這工作,因爲宏觀CreateFile
是一個函數宏(即它需要的參數在括號中的列表);名稱後的右括號與使用類似函數的宏的語法不匹配,所以預處理器不會擴展它。
當然,「正確」的解決方案是正確命名功能,即,create_file
。 <g>
I'<g>''ed。 – Potatoswatter 2013-05-30 09:49:42
「不要使用名稱......」可能很難完成,因爲認真對待它應該是「不要使用與OS API調用匹配的名稱,也不要使用與其他常用API調用的名稱匹配的名稱,在某一天成爲API調用...「;-)更好地堅持」只在你的代碼的一小部分內容中使用第三方API「。 – 2013-04-26 13:52:40
是的,我同意你評論的兩個方面。一些API名稱也非常通用,因此很難避免與它們發生衝突......並且將與系統相關的代碼粘貼到單獨的源文件中肯定是一個好主意 - 也可以移植到不同的操作系統(或不同的第三方庫,等)更簡單。 – 2013-04-26 13:59:59