至少某些C預處理程序可讓您將宏的值(而不是其名稱)通過一個類似于函數的宏傳遞給另一個對其進行字符串化的宏:#define STR1(x) #x#define STR2(x) STR1(x)#define THE_ANSWER 42#define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */這里的示例用例。這確實有效,至少在GCC和Clang(都與中-std=c99)中都有效,但是我不確定它在C標準術語下如何工作。C99是否可以保證這種行為?如果是這樣,C99如何保證?如果不是,行為在什么時候從C定義變?yōu)镚CC定義?
2 回答

BIG陽
TA貢獻1859條經驗 獲得超6個贊
是的,有保證。
之所以可以使用它,是因為宏的參數本身是宏擴展的,除非宏參數名稱出現在宏主體中且?guī)в凶址畼俗R符#或令牌標記##。
6.10.3.1/1:
...確定了調用類似函數的宏的參數后,將進行參數替換。替換列表中的參數,除非在?;?#預處理令牌之前或在##預處理令牌之后(請參見下文),否則在擴展其中包含的所有宏之后,將用相應的參數替換...
因此,如果這樣做,STR1(THE_ANSWER)則會得到“ THE_ANSWER”,因為STR1的參數未進行宏擴展。然而,STR2的參數是當它代入STR2的定義中,其因此給出STR1的參數宏擴展42,與“42”的結果。

冉冉說
TA貢獻1877條經驗 獲得超1個贊
正如史蒂夫(Steve)所指出的那樣,這是有保證的,并且自C89標準以來一直得到保證-該標準是將宏中的#和##運算符整理成代碼的標準,并強制遞歸擴展args中的宏,然后且僅當且僅當主體不對參數應用#或##。在這方面,C99與C89相同。
- 2 回答
- 0 關注
- 358 瀏覽
添加回答
舉報
0/150
提交
取消