出於某種原因,我需要暫時禁用頭文件中的一些宏,並且#undef MACRONAME
將使代碼編譯,但它將取消現有的宏。如何暫時禁用C/C++中的宏擴展?
有沒有辦法只是禁用它?
我應該提到你並不真正知道宏的值,並且我正在尋找一個交叉編譯器解決方案(至少應該在GCC和MSVC中工作)。
出於某種原因,我需要暫時禁用頭文件中的一些宏,並且#undef MACRONAME
將使代碼編譯,但它將取消現有的宏。如何暫時禁用C/C++中的宏擴展?
有沒有辦法只是禁用它?
我應該提到你並不真正知道宏的值,並且我正在尋找一個交叉編譯器解決方案(至少應該在GCC和MSVC中工作)。
在MSVC中,您可以使用push_macro
編譯指示,GCC supports它與Microsoft Windows編譯器兼容。
#pragma push_macro("MACRONAME")
#undef MACRONAME
// some actions
#pragma pop_macro("MACRONAME")
很高興知道這是存在的,所以很好的答案,但這是可怕的。 – Novelocrat
這就是爲什麼人們不斷告訴我們像*宏是邪惡的東西。遲早有人會創建一個名爲'new'的宏來做一些愚蠢的事情...... –
@JohnLeidegren好吧,我們現在是中途了。 [** misconstrued「邪惡」宏的示例**](http://stackoverflow.com/q/18167990/319204)。 – TheCodeArtist
僅使用由標準C(C89,C99或C11)定義的設施,唯一的「禁用」機制是#undef
。
問題是沒有'重新啓用'機制。
正如其他人指出的那樣,如果包含的宏定義的頭文件(這些不能重複;函數和變量聲明可以重複)結構化,以便它不包含任何的typedef或enum聲明,然後你可以使用#undef
這個宏,在沒有生效的宏的情況下做你所需要的,然後重新包含這個頭,可能在定義它的保護以防止重新包含之後。
如果在頭文件中沒有定義這些宏,當然,直到您重構代碼以使它們位於頭文件中,您纔會被卡住。
另一個技巧是可用的 - 如果宏是類似函數的宏而不是類似宏的宏。
#define nonsense(a, b) b /\= a
int (nonsense)(int a, int b)
{
return (a > b) ? a : b;
}
功能nonsense()
是,儘管之前立即宏定義的罰款。這是因爲一個宏函數 - 對於一個類似函數的宏 - 必須緊接着一個左括號(給出或佔用空格,可能包括註釋)。在函數定義行中,'廢話'之後的標記是一個右括號,因此它不是對宏的調用。
在宏觀一個說法無類對象宏,關鍵是行不通的:
#define nonsense min
int (nonsense)(int a, int b)
{
// Think about it - what is the function really called?
return (a > b) ? a : b;
}
此代碼定義就是所謂min
,是無意義的虛假功能。並沒有保護宏觀。
這就是爲什麼標準要小心定義哪些名稱空間是爲'實現'保留的原因之一。如果這些名稱是爲實現保留的,那麼允許實現爲其需要或需要的任何目的定義任何類型的宏(它類似於函數或類似於對象的類型)。如果您作爲The Implementation服務的使用者嘗試使用或定義爲實現保留的名稱,則必須意識到您的代碼遲早可能會中斷,並且這將是您的錯,而不是The實現。
Upvote for'(廢話)'解決方法。真棒! –
宏來自一些頭文件,所以你應該有權訪問它們的值。然後,您可以不喜歡
#include <foo.h> // declares macro FOO
// Do things with FOO
#undef FOO
// do things without FOO
#include <foo.h> // reenable FOO
你的頭然後應沿着這些線路設計
#ifndef FOO
#define FOO do_something(x,y)
#endif
確保你沒有其他的東西不是你在這個頭文件中啓用/禁用的宏,否則會出現重新聲明的問題。 –
同時確保'
重新包含頭文件可能會導致其他問題,除非頭文件是專門設計用於這種方式的。 –
編輯:
你可以認爲它就是這麼簡單:
#ifdef macro
#define DISABLED_macro macro
#undef macro
#endif
// do what you want with macro
#ifdef DISABLED_macro
#define macro DISABLED_macro
#endif
但它不是(就像下面的例子演示ES)!
#include <iostream>
#include <limits>
#include <windows.h>
#ifdef max
#define DISABLED_max max
#undef max
#endif
int main()
{
std::cout << std::numeric_limits<unsigned long>::max() << std::endl;
#ifdef DISABLED_max
#define max DISABLED_max
#endif
std::cout << max(15,3) << std::endl; // error C3861: "max": identifier not found
return 0;
}
使用在宏觀和再包括原標題#undef
也不可能奏效,因爲頭警衛。 所以剩下的就是使用push_macro/pop_macro #pragma
指令。
#pragma push_macro("MACRO")
#undef MACRO
// do what you want
#pragma pop_macro("MACR")
打我40秒左右... – KitsuneYMG
除了它工作?是不是它「恢復」了宏,因此它會擴展到「宏」(這是我看到,當我添加缺少的部分)?可能是一個完整的使用示例? – UncleBens
這不起作用 - 請參閱我對kts的評論。 – Novelocrat
我想你有一個令人信服的理由,實際上已經結束在這個宏的混亂?我在這裏想不到一個...... – sbi