Yoh2の日記: [C/C++規格: 2] コメント除去タイミング 2
C/C++規格ネタ、シリーズ化すると言っておきながら、2回目までほぼ一年。意外とネタがないのぅ。
で、今回のネタはコメント除去のタイミング。
Cのソースがコンパイルされるときの流れは、いろいろ端折っておおまかに書くと、
- \ + 改行の除去
- コメント→空白への置き換え
- 前処理指令実行
- 意味解析
てな順番になるらしい。
\ + 改行は、長いマクロを書く時にお世話になったことのある人も多いと思う。\ + 改行の除去がプリプロセッサが走る前に行われるため、本来一行ですべて書かなくてはならない#define等を複数行に分けて書くことができる、という寸法。
ここでふと気になったのがコメントを空白に置き換えるタイミング。これまたプリプロセッサが走る前に行われることになっている。そして、Cのコメントは複数行に渡って書くことができる。ということは、
#define N (1/*
*/+ 1)
と書くと、プリプロセッサが走る前にコメントが空白に置き換えられるため、
#define N (1 + 1)
と変形され、結果、マクロ N が (1 + 1) だと定義されることになる。つまり、コメントを使うことによって、複数行に渡るマクロを書くことができるというワケ。
まあ、見にくいからやらないけど。
<余談>
昔、興味本位で、コメントの開始、終了の記号をマクロに置き換えられるかどうか、以下のコードで試してたことがあるけど失敗。
コメントの置き換えのタイミングがプリプロセッサより前だから失敗は当然だよなぁ、と、規格書を読んでようやく納得した次第。
#define CONCAT(a, b) a ## b
#define BEGIN_COMMENT CONCAT(/,*)
#define END_COMMENT CONCAT(*,/)
BEGIN_COMMENT
ここはコメント?
END_COMMENT
</余談>
一方私は (スコア:1)
ここのところが気になって、以下のようなコードを書いてみたのでした。
/\
*
ここはコメント?
*\
/
結果は…試してみるのが手っ取り早いかと。
Re:一方私は (スコア:1)
あと、C++やC99ではこんなことも。
巧妙に潜伏したバグは心霊現象と区別が付かない。