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

MSC17-C. case 句に関連付けられた一連の文は break 文で終了する

switch 文は複数の case 句と、1つの default 句で構成される。default 句は省略可能だが、指定することが推奨される(「MSC01-C. 論理的な完全性を追求する」を参照)。case 句に続く一連の文は、規約上は break 文で終了することになっている。これを省略すると、制御の流れは switch 文のブロック内の次の case まで進む。break 文は必須ではないため、これを省略してもコンパイラの診断メッセージは出力されない。誤って省略されると、予期せぬ制御の流れを引き起こすことがある。

違反コード

以下のコード例では、widget_typeWE_W の場合に break 文がない。したがって、widget_typeWE_X の場合にのみ実行されるべき文が、widget_typeWE_W の場合にも実行される。

enum WidgetEnum { WE_W, WE_X, WE_Y, WE_Z } widget_type;
widget_type = WE_X;

switch (widget_type) {
  case WE_W:
    /* ... */
  case WE_X:
    /* ... */
    break;
  case WE_Y:
  case WE_Z:
    /* ... */
    break;
  default: /* 発生しないはず */
  /* エラー処理 */
}

適合コード

以下の解決法では、case 句に続く文はそれぞれ break 文で終了している。

enum WidgetEnum { WE_W, WE_X, WE_Y, WE_Z } widget_type;
widget_type = WE_X;

switch (widget_type) {
  case WE_W:
    /* ... */
    break;
  case WE_X:
    /* ... */
    break;
  case WE_Y:
  case WE_Z:
    /* ... */
    break;
  default: /* 発生しないはず */
  /* エラー処理 */
}

widget_typeWE_Y の場合には、break 文は必要ない。これは、次の case 句(WE_Z)の前に文がないため、WE_YWE_Z の両方が同様に処理されるからである。

制御の流れに影響を及ぼさないため、デフォルトケースのあとに break 文は必要ない。

例外

MSC17-EX1: switch 文の最後の句には、最後の break は必要ない。

MSC17-EX2:制御の流れを意図的に複数の case ラベルを通るようにする場合は、break 文を省略することが可能である。その場合、制御の流れが通常どおりでないことを明示的に文書化しておくべきである。

enum WidgetEnum { WE_W, WE_X, WE_Y, WE_Z } widget_type;
widget_type = WE_X;

switch (widget_type) {
  case WE_W:
    /* ... */
    /* break がないので、WE_X のケースも処理する */
  case WE_X:
    /* ... */
    break;
  case WE_Y: case WE_Z:
    /* ... */
    break;
  default: /* 発生しないはず */
  /* エラー条件の処理 */
}

リスク評価

break 文を省略すると予期せぬ制御の流れが発生する。

レコメンデーション 深刻度 可能性 修正コスト 優先度 レベル
MSC17-C P6 L2
自動検出

Compass/ROSE はこのレコメンデーションの違反を検出できる。

参考情報
翻訳元

これは以下のページを翻訳したものです。

MSC17-C. Finish every set of statements associated with a case label with a break statement

Top へ

Topへ
最新情報(RSSメーリングリストTwitter