首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 前置處理器 ## 連接符:為何 GCC 編譯失敗與雙層宏定義技巧

     編輯:程式設計綜合問答

代碼片段:

#define TR(m,n,p) m##n##p
int main() {
    printf("%s\n", TR("abc","xy","yz"));
    return 0;
}

在 GCC 下編譯報錯:pasting "abc" and "xy" does not give a valid preprocessing token。

根本原因

##(Token Pasting)運算子要求運算結果必須為合法的前置處理器 Token(識別字、常數、運算子等)。字串常數 "abc" 經連接後變成 "abcxy",但 "abc" "xy" 在前置處理階段是兩個獨立字串常數 Token,而非單一 Token,故違反規範。

解決方案:雙層宏展開

#define TR_IMPL(m,n,p) m##n##p
#define TR(m,n,p) TR_IMPL(m,n,p)

#define A abc
#define B xy
#define C yz

int main() {
    printf("%s\n", TR(A,B,C)); // 展開為 abcxyz -> 單一識別字
    return 0;
}

關鍵:先定義不帶引號的識別字巨集(A, B, C),再透過雙層宏強制參數完整展開後才進行 ## 連接,結果 abcxyz 為合法識別字。

進階應用:自動生成變數/函數名

#define DECLARE_VAR(prefix, num) int prefix##num = 0;
DECLARE_VAR(val, 1)  // 展開為 int val1 = 0;
DECLARE_VAR(val, 2)  // 展開為 int val2 = 0;

參考資源

詳細解析請見:C 前置處理器 ## 連接符深度解析與雙層宏技巧

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved