34140


プリプロセッサに詳しい方にお聞きしたいのですが[、ここの](https://www.jpcert.or.jp/sc-
rules/c-pre05-c.html)  
このコードがどういう順番で展開されるために、NGなのか

[code]

    #define str(s) #s　　　①
    #define foo 4　　　　　　②
    
    str(foo);
    
[/code]

下ではなぜOKなのか

[code]

    #define xstr(s) str(s)
    #define str(s) #s
    #define foo 4
    
[/code]

私には理解できませんでした。

[code]

    #define JOIN(x, y) JOIN_AGAIN(x, y)
    #define JOIN_AGAIN(x, y) x ## y
    
[/code]

上ののコードもわかりませんでした。


CC BY-SA 3.0
2017-04-18T05:24:49.270
34093
2017-04-20T03:51:12.200
2017-04-20T03:03:32.687
10455
10455
question
c
マクロの二段階展開について教えてください。


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` されているかのごとくに振舞う仕様です。

[code]

    #define __FILE__ "example.c"
    #define __LINE__ 17
    
[/code]

リンク先の `static_assert` の最終展開結果が `assertion_failed_at_line___LINE__` ではおいしくなくて
`assertion_failed_at_line_17` であってほしいわけです。であれば `#` や `##` の直接対象に `__LINE__`
という字句ではなくて、その展開結果 `17` を与えたいわけです。そのためにはもう一段マクロをかませて、１段目には `#` や `##`
を使わないことでマクロ展開を行わせ、２段目はその展開結果に `#` や `##` を適用し結合させる、ことで目的を達成できることになります。


CC BY-SA 3.0
2017-04-18T06:38:10.163
34095
2017-04-19T06:42:06.750
2017-04-19T06:42:06.750
8589
8589
34093
answer


JISの文章を引用すると

> 実引数の中のすべてのマクロを展開する。ただし、置換内容列の中の次の仮引数は除く  
>  \- 前処理字句 # または ## が前にある仮引数  
>  \- 前処理字句 ## が後に続く仮引数  
>  JIS X 3014:2003 (ISO/IEC 14882:2003) 16.3.1 実引数代入  
>  JIS X 3010:2003 (ISO/IEC 9899:1999) 6.10.3.1 実引数置換

端的に説明すると、引数の先が#だったり##だったら置換しません。ということ  
なので

[code]

    #define str(s) #s　　　①
    #define foo 4　　　　　　②
    
[/code]

こう書いてしまうと

[code]

    str(foo);
    
[/code]

引数の先が#なので②は置換されずに`"foo"`と扱われてしまう。そこで、以下のように書く

[code]

    #define str(s) str_cp(s) 
    #define str_cp(s) #s　　　◎
    #define foo 4　　　　　　
    str(foo);
    
[/code]

すると無意味に感じられる◎は一度目の置換動作で

[code]

    #define str_cp(s) #s　　　◎
    str_cp(4);
    
[/code]

となり、最終的に`"4"`と望む結果が得られる。  
実行順序を考えると#や##が先で定数やマクロ関数が次という考え方もできる。


CC BY-SA 3.0
2017-04-20T03:45:08.457
34140
2017-04-20T03:51:12.200
2017-04-20T03:51:12.200
10455
10455
34093
answer