Home > ラーニング > セキュアコーディング > C セキュアコーディングスタンダード > 01. プリプロセッサ (PRE)
マクロをつかって複数にわたる文をひとつのグループとして実行することがよくある。
一般に、この手のタスクにはインライン関数の方が適しているが(「PRE00-C. 関数形式マクロよりもインライン関数やスタティック関数を使う」を参照)、実際には使えないことも多い(たとえば、マクロを使って異なる型の変数に対する演算を行うときなど)。
複数にわたる文をマクロで使う場合、これらの文は do-while ループで構文的にひとつにまとめるべきである。そうすることで、if 節など単一の文や文のブロックがくることを想定するところでも安全に出現することができる。
以下のコード例では、複数の行がひとまとめにされていない。
/* * 2つの値を入れ替える * tmp 変数が定義されていること */ #define SWAP(x, y) \ tmp = x; \ x = y; \ y = tmp
このマクロは普通の文中では正しく展開されるが、if 文の中の then 節では正しく展開されない:
int x, y, z, tmp; if (z == 0) SWAP( x, y);
これは展開されると次のようになる
int x, y, z, tmp; if (z == 0) tmp = x; x = y; y = tmp;
これは明らかにプログラマが意図したところではない。
マクロを do-while ループの中に包み込むことでこの問題を緩和することができる。
/*
/*
* 2つの値を入れ替える
* tmp 変数が定義されていること
*/
#define SWAP(x, y) \
do { \
tmp = x; \
x = y; \
y = tmp; } \
while (0)
do-while ループは必ず一度だけしか実行されないだろう。
不適切に包まれたマクロ文は、予期せぬ、また原因をつきとめるのが困難な動作を引き起こすおそれがある。
| レコメンデーション | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
|---|---|---|---|---|---|
| PRE10-C | 中 | 中 | 低 | P12 | L1 |