マクロ関数

たとえばint変数の値を入れ替えるマクロを考える。初めに考えるだろうマクロはこんな感じか

#define SWAP(x, y) int tmp; tmp = x; x = y; y = tmp; 

しかし、これだとC89準拠にならない。ブロックの途中で変数の宣言ができない制限があるためだ。よって次の段階ではこうなる。

#define SWAP(x, y) {int tmp; tmp = x; x = y; y = tmp; }

これでほとんどの場合OKなのだが以下のような場合に問題になる。

if (x > 0)
   SWAP(x, y);
else 
   printf("xは正の整数を入力してください");

私はほとんどifの{}は省かないのでまず困らないのだけれど、汎用のライブラリとしては問題がある。ということで、こういう場合の常套手段は以下のマクロ。

#define SWAP(x, y) do {int tmp; tmp = x; x = y; y = tmp; } while(0)

セミコロンをつけることで文になるのは式文、do-while、ジャンプ文であり、do{}while(0)は見た目以外は副作用がないことを利用している。


ところで後輩にこんなマクロじゃダメですか?と質問された。

#define SWAP(x, y) ({int tmp; tmp = x; x = y; y = tmp; })

複文は式では無いので、コンパイルエラーになりそうだが、gccではこれが通った。念のため-ansiオプションをつけたがやはり通る。動作もdo-whileと同じように使える。

文法的に?と思ってbcc32, LSI-C86試食版, VC++Expressで試してみたが全滅だった。gccは懐が広く、先進的なのはいいのだが、オプションつけたら厳密に文法解釈してほしい気がする。