[英]How to define a C macro that uses another macro?
我有以下場景......
Header 文件:
#define TRIG_INDEX 200
#define PATH(target_p) some.path.to.target##target_p
源文件:
read_from_target(PATH(TRIG_INDEX));
由於PATH
宏將target_p
附加到最后的文本中,因此編譯失敗,因為some.path.to.targetTRIG_INDEX
不是有效路徑。
我期待在上述情況下得到read_from_target(some.path.to.target200)
。
我如何(如果有的話)定義宏來接受這種情況?
參數必須由宏擴展:
#define TRIG_INDEX 200
#define PATH_TARGET(x) some.path.to.target##x
#define PATH(target_p) PATH_TARGET(target_p)
類似函數的宏的預處理器宏擴展/替換規則相當復雜。 基本上它按以下順序執行:
宏名稱后面的東西稱為替換列表。 在這種情況下PATH_TARGET(target_p)
- PATH
應該被替換的東西。
##
或#
與宏參數一起出現意味着該參數被其相應的預處理器標記序列(如果適用)替換。 在這種情況下,參數target_p
被替換為TRIG_INDEX
,因此我們得到some.path.to.target##TRIG_INDEX
創建新的預處理器令牌some.path.to.targetTRIG_INDEX
,這與預期不符。
其他宏參數得到擴展。 不適用於這里。
然后重新掃描替換列表以查找要擴展的宏名稱,但為時已晚,因為已經發生了與##
的預處理器標記連接。
上面的“其他宏參數得到擴展”部分對於解決問題很有用。 因此替換列表中的宏參數優先於宏名稱。 我們可以通過添加一個輔助宏來利用這一點:
#define TRIG_INDEX 200
#define EXPAND(tgt) some.path.to.target##tgt
#define PATH(target_p) EXPAND(target_p)
現在在PATH
的替換列表的擴展中,我們首先得到宏參數擴展: taget_p
被替換,我們得到EXPAND(TRIG_INDEX)
。 然后重新掃描替換列表以查找要替換的宏名稱,預處理器找到兩個這樣的宏名稱: EXPAND
和TRIG_INDEX
。 兩者都被擴展,因此TRIG_INDEX
被替換為200
。 然后EXPAND
根據相同的規則遞歸擴展( ##
強制將該宏參數tgt
擴展為200
,然后再進行其他任何操作)。
有關詳細信息,請參閱 C17 標准第 6.10.3 章 - 這一章也是指定 # 和 ## 運算符的行為的一章。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.