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。