簡體   English   中英

C 預處理器:用令牌連接宏調用

[英]C Preprocessor: concatenate macro call with token

我正在嘗試將一個宏調用與一個令牌連接起來以創建一個新的,例如:

#define TEST(X) X ## _TEST
#define CONCAT(X) TEST(X) ## _CONCAT

CONCAT(OK);

然后我用gcc -E檢查 output ; 我想得到OK_TEST_CONCAT; 但我得到一個錯誤:

error: pasting ")" and "_CONCAT" does not give a valid preprocessing token

如果我刪除##我沒有得到任何錯誤,但 output 是OK_TEST _CONCAT;

這是一個最小的示例,所以這里最簡單的方法是將所有內容組合在一個宏中,但要知道我不可能擺脫對TEST的第一次調用。 有沒有辦法刪除那個空間?

謝謝

編輯:

好吧,從混亂來看,也許我的例子有點簡單了,那是我的錯。 這是一個更合理的用例:

我希望某個 header 中的所有原型都以該 header 中定義的PREFIX作為前綴。

協議.h:

#define EXPAND(X) EXPAND_HELPER(X)
#define EXPAND_HELPER(X) X
#define PROTO(NAME) PREFIX ## NAME

其他.h:

#include <proto.h>

#define PREFIX other

int PROTO(test)(int a, int b);
...

我想要的是other.h中的所有原型都具有這種形式: int other_test(int a, int b); . 但實際上他們有這種形式: int PREFIX_test(int a, int b); . 谷歌搜索后我發現我需要強制PREFIX重新掃描,所以我嘗試了這個:

#define PROTO(NAME) EXPAND(PREFIX) ## NAME

這引發了我的問題。 現在,如果我查看@Lundin 的回答,我可以對其進行調整以提供我想要的內容:

解決方案:

#define PROTO(NAME) PROTO_HELPER(PREFIX, NAME)
#define PROTO_HELPER(PREFIX, NAME) PROTO_EXPAND(PREFIX, NAME)
#define PROTO_EXPAND(PREFIX, NAME) PREFIX ## NAME

謝謝!

在調用使用 ## 或 # 的類函數宏之前,必須展開所有預處理器標記。 因為 ## 或 # 在宏擴展之前應用。 在您的情況下TEST(X)僅將X擴展為TEST(OK) ,然后預處理器嘗試將TEST(OK)_CONCAT粘貼,這將不起作用。 對於每次連接標記的嘗試,您必須首先在 ## 之前展開所有宏,這是由強制重新掃描/替換的額外輔助宏完成的。

給定#define TEST(X) X ## _TEST的人為解決方案是這樣的:

#define CONCAT(X) EXPAND_HELPER(TEST(X)) // expands TEST(X) to TEST(OK)

-->

#define EXPAND_HELPER(X) CONCAT_HELPER(X, _CONCAT) // expands TEST(OK) to OK_TEST

-->

#define CONCAT_HELPER(X,Y) X ## Y

那是:

// NOTE: contrived solution, avoid

#define TEST(X) X ## _TEST
#define CONCAT_HELPER(X,Y) X ## Y
#define EXPAND_HELPER(X) CONCAT_HELPER(X, _CONCAT)
#define CONCAT(X) EXPAND_HELPER(TEST(X))

...

int CONCAT(OK) = 1; // becomes int OK_TEST_CONCAT = 1;

一個更簡單的解決方案是:

#define CONCAT(X) X ## _TEST ## _CONCAT

暫無
暫無

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

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