簡體   English   中英

C ++停止預處理器宏擴展

[英]C++ Stop Preprocessor Macro Expansion

這是我的示例代碼https://godbolt.org/z/VKgKik

#define delete MyCustomDelete(__FILE__, __LINE__), delete

#define CAT(X,Y) CAT2(X,Y)
#define CAT2(X,Y) X##Y
#define CAT_3(X,Y,Z) CAT(X,CAT(Y,Z))    


class A {
    A() = CAT_3(de,le,te);
};

設置godbolt示例以顯示預處理器輸出。 目標是在預處理器傳遞結束時我想要輸出代碼

class A {
    A() = delete;
};

目前在那里顯示“ThisShouldNotshowUp”。 我認為使用##運算符會阻止預處理器重新擴展,但事實並非如此。

我意識到刪除“#define delete”會解決問題,但我需要在那里定義。 我創建一個與delete同名的宏的原因是因為我希望能夠跟蹤新聞和刪除,如果發生內存泄漏,我可以看到代碼行代碼。 因此,這個宏意味着我可以繼續在我的代碼中使用關鍵字delete,並且免費填寫文件和行號。 據我所知,除了定義刪除宏之外,沒有其他方法可以實現此功能。 這是問題的症結所在。 刪除宏給了我一個強大的調試工具,但它刪除了一個有用的語言功能供我使用。

您無法通過展開宏來創建預處理標記,該標記是類對象宏的名稱。 n3337的相關部分是[cpp.rescan] 我引用其中第一段的縮短部分。

替換列表中的所有參數都被替換后, ###處理已經發生[...]。 然后重新掃描生成的預處理標記序列,以便替換更多的宏名稱。

盡管存在這個問題,但技術上禁止delete是宏名稱,在重新掃描時無法阻止識別宏名稱。

您可能混淆了這樣一個事實,即##運算符確實使用它的參數而不進行擴展,並認為##結果不會進行宏擴展。

您正在嘗試做的事情是不可能的,正如Michael Karcher的回答所述: #define delete已經使程序格式錯誤,並且無法避免擴展類似對象的宏(在其自身的擴展之外)。

但是,對於問題中詳述的特定用例,可以采用解決方法。 您可以將#define delete放入頭文件(讓我們稱之為debug_delete.hxx ),如下所示:

#ifdef delete
# undef delete
#endif
#define delete MyCustomDelete(__FILE__, __LINE__), delete

然后,創建另一個頭文件(讓我們稱之為normal_delete.hxx ):

#ifdef delete
# undef delete
#endif

特別要注意的是,這些標題中沒有機制可以防止多重包含; 事實上,我們希望它們可以包含任意次數。

然后,包裝必須使用= delete;代碼= delete; 在適當的#include指令中:

class A {
#include "normal_delete.hxx"
    A() = delete;
#include "debug_delete.hxx"
    ~A() { delete p; }
};

(是的,這很丑陋,但是你所做的事情首先是丑陋的,所以可能需要使用丑陋的代碼才能使它工作)。

大概你想使用一個宏,這樣你就可以打開和關閉刪除跟蹤。 如果你只是在源代碼上使用它,而不是試圖改進它來轉換現有的C ++,你可以使用類似函數的宏來實現你想要的可選跟蹤。

#define TRACK_DELETES 0
#if TRACK_DELETES
  #define DELETE( a ) \
    do { MyCustomDelete( __FILE__, __LINE__ ); delete (a); } while (0)
  #define DELETEALL( a ) \
    do { MyCustomDelete( __FILE__, __LINE__ ); delete [] (a); } while (0)
#else
  #define DELETE( a ) do { delete (a) ; } while(0)
  #define DELETEALL( a ) do { delete [] (a) ; } while(0)
#endif

int main(){

  DELETE( A );
  DELETEALL( B );

  return 0;
}

gcc -E下將TRACK_DELETES設置為0或1,看看是否符合要求。

您需要單獨保留裸delete關鍵字,以便可以正確使用它。

暫無
暫無

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

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