質問: プリプロセッサに詳しい方にお聞きしたいのですが、ここの このコードがどういう順番で展開されるために、NGなのか ``` #define str(s) #s 1 #define foo 4 2 str(foo); ``` 下ではなぜOKなのか ``` #define xstr(s) str(s) #define str(s) #s #define foo 4 ``` 私には理解できませんでした。 ``` #define JOIN(x, y) JOIN_AGAIN(x, y) #define JOIN_AGAIN(x, y) x ## y ``` 上ののコードもわかりませんでした。
回答: JIS X 3014:2003 (ISO/IEC 14882:2003) 16.3.1 実引数代入 JIS X 3010:2003 (ISO/IEC 9899:1999) 6.10.3.1 実引数置換 > > 実引数の中のすべてのマクロを展開する。ただし、置換内容列の中の次の仮引数は除く > > - 前処理字句 `#` または `##` が前にある仮引数 > > - 前処理字句 `##` が後に続く仮引数 > > > これがどういう意味か、というと `#` あるいは `##` の対象は、そのマクロの仮引数に与えられた字句(ソースコードに記述した文字の列)そのものです。この質問での提示例 `str(foo)` の引数は `foo` という字句ですが、 `foo` が `#define` されてても置換しない、あくまで `foo` という字句であるものとして扱う、ということです。 提示 `str` は字句を文字列化するマクロなので、結果は `"foo"` となります。 `"4"` とはなりません。 さて `__FILE__` と `__LINE__` は `#define` されているかのごとくに振舞う仕様です。 ``` #define __FILE__ "example.c" #define __LINE__ 17 ``` リンク先の `static_assert` の最終展開結果が `assertion_failed_at_line___LINE__` ではおいしくなくて `assertion_failed_at_line_17` であってほしいわけです。であれば `#` や `##` の直接対象に `__LINE__` という字句ではなくて、その展開結果 `17` を与えたいわけです。そのためにはもう一段マクロをかませて、1段目には `#` や `##` を使わないことでマクロ展開を行わせ、2段目はその展開結果に `#` や `##` を適用し結合させる、ことで目的を達成できることになります。