C 語言 stringify 技巧
一般 #define
macro 不會將 parameter 展開成字串,只會把 parameter 放到對應位置,例如:
1 | <?php |
1 |
|
經過 preprocess:
1 | $ cpp stringify.c |
如果在 parameter 前加 #
,preprocessor 會把 actual argument 變成字串,稱為 Stringizing。用個例子說明:
1 |
|
經過 preprocess(只是例子,code 本身不太 make sense):
1 | int main() { |
Linux kernel 使用這個技巧將 macro 展開成字串。
__stringify
定義在 include/linux/stringify.h
:
1 |
為什麼 __stringify
要 define 兩次呢?
在 Argument Prescan 提到 macro 的參數如果也是 macro,一般在被替換進 macro body 前就會被展開,但如果是 stringized 則不會被展開。
1 |
|
這例子裡 __stringify_1(FOO)
因為是 stringized 的 macro 參數,所以 FOO
不會被展開,macro 替換後最後變成 "FOO"
。而 __stringify(FOO)
會先展開 FOO
並替換,變成 __stringify_1(bar)
,接著再 scan 一次將 macro 展開為 "bar"
。
__stringify
define 兩次是為了讓參數可以使用 macro。像上面的例子,通常期望 __stringify(FOO)
得到 "bar"
而非 "FOO"
。
...
是跟 function 一樣的不定參數,可參考 Variadic Macros。