簡體   English   中英

取消定義並重新定義__cplusplus宏

[英]undefine and redefine the __cplusplus macro

我想取消定義並重新定義__cplusplus宏,但是編譯錯誤: __cplusplus was not declared in this scope

#define TEMP_VERSION __cplusplus // temporary macro to hold the __cplusplus  containt
#undef __cplusplus
#define __cplusplus TEMP_VERSION  // redefine __cplusplus

#define AA 111
#undef AA
#define AA 111

int main()
{
    cout << "__cplusplus = "<<__cplusplus<<endl; // It doesn't work
    cout << "AA = "<<AA<<endl; // It works

    return 0;
}
  • 問題1:為什么它不能與__cplusplus一起使用,但是可以與AA

我知道這確實很丑陋,但是未定義宏的原因是我正在使用第三方軟件,其中他們誤用了#ifdef __cplusplus ,我的意思是#ifdef __cplusplus ... #endif有誤。 因此,我沒有更改他們的軟件,而是選擇執行以下操作

#define TEMP_VERSION __cplusplus
#undef __cplusplus
#include <third_party_sw.h>
#define __cplusplus TEMP_VERSION
  • 問題2:您認為這是一種好方法嗎?

根據C ++標准([cpp.predefined,3-4]):

預定義宏的值( __FILE____LINE__除外)在整個轉換單元中保持不變。 如果此子節中的任何預定義宏名稱或定義的標識符是#define或#undef預處理指令的主題,則該行為是未定義的。

換句話說, __cplusplus宏不僅僅是編譯器在將控制權移交給您之前通過定義開始的內容; 它是一個不變的常數,不能更改,並且是嘗試更改的錯誤。

至於是否可行,是否是一個好方法:取決於上下文,但可能並非如此。 這類“愚弄標頭”的黑客( #define private public ,有人嗎?)很少有效,而且永遠都不安全。

編輯:哦,順便說一句,即使您確實有一個宏,保存/恢復還是合法的,但這並不是正確的方法。 請參閱我可以重新定義C ++宏,然后重新定義它嗎?

這是因為__cplusplus由編譯器預定義。

從技術上講,定義它們的是預處理器,但是根據哪個編譯器調用預處理器,輸出可能會有所不同。 嘗試運行此:

$ g++ -dM -E - </dev/null

輸出是所有預處理器定義的(在這種情況下)此命令運行的預處理器所產生的。

請注意, __cplusplus不會出現在此處。 它是每個C ++編譯單元內置的。

(將clang++替換為g++時,該方法同樣有效。)

問題1:為什么它不能與__cplusplus一起使用,但是可以與AA一起使用

因為__cplusplus是預定義的宏,並且(未定義)它的行為是未定義的:

標准草案[cpp.predefined]

如果此子節中的任何預定義宏名稱或定義的標識符是#define或#undef預處理指令的主題,則該行為是未定義的。 ...

AA不是預定義的宏,標識符也不是保留的。 可以(重新)定義它。


問題2:您認為這是一種好方法嗎?

(重新)定義保留標識符永遠不是一個好方法。 甚至重新定義用戶定義的宏也是一個可疑的主張。

如果可能的話,理想的方法可能是修復第三方軟件。 或者,您可以為沒有問題的軟件編寫自定義標頭。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM