JPCERT コーディネーションセンター

安全・安心なIT社会のための、国内・国際連携を支援する

お問い合わせ サイトマップ English

Home > ラーニング > セキュアコーディング > C セキュアコーディングスタンダード > 01. プリプロセッサ (PRE)

  1. HTTPS

01. プリプロセッサ (PRE)

最終更新: 2010-07-26

PRE10-C. 複数にわたる文からなるマクロは do-while ループで包む

マクロをつかって複数にわたる文をひとつのグループとして実行することがよくある。

一般に、この手のタスクにはインライン関数の方が適しているが(「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
参考情報
  • [ISO/IEC PDTR 24772] "NMP Pre-processor Directions"
翻訳元

PRE10-C. Wrap multi-statement macros in a do-while loop

Top へ