メインコンテンツ

switch case の break がありません

switch ステートメントの case ブロックが break[[fallthrough]]、または説明コメントで終了していない

説明

この欠陥は、switch ステートメントの case ブロックが break[[fallthrough]]、または説明コメントで終了していない場合に発生します。

case ブロックの最後のエントリがコード コメントの場合の例:

switch (wt)
    {
      case WE_W:
        do_something_for_WE_W();
        do_something_else_for_WE_W();
        /* fall through to WE_X*/
      case WE_X:
        ...
    }
Polyspace は、break がないのは意図的であると判断され、欠陥が発生しないことを前提とします。

リスク

switch case に break ステートメントがないと、次の switch case が実行されます。この動作が意図的でない場合、switch case のコードが意図せず実行され、switch が予期しない結果で終わる可能性があります。

修正方法

break ステートメントを忘れた場合は、switch case の末尾に追加します。

強調表示された switch case を break しない場合は、コードにコメントを追加して、この case に続いて次の case が実行される理由を示します。このコメントにより、結果から欠陥が削除され、コードの保守が容易になります。

テンプレート関数の場合など、欠陥チェッカーが case ステートメントの末尾にあるコメントを無視することがあります。意図的に次の case まで続行することを、より明確に示す方法として、以下の fallthrough 属性のいずれかを使用する方法があります。(可能な場合)

  • [[fallthrough]]:C++17 以降で使用できます。

  • [[gnu::fallthrough]] および [[clang::fallthrough]]: GCC コンパイラと Clang コンパイラで使用できます。

  • __attribute__((fallthrough)):GCC コンパイラで使用できます。

すべて展開する

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

extern void demo_do_something_for_WE_W(void);
extern void demo_do_something_for_WE_X(void);
extern void demo_report_error(void);

void bug_missingswitchbreak(enum WidgetEnum wt)
{
    /*
      In this non-compliant code example, the case where widget_type is WE_W lacks a
      break statement. Consequently, statements that should be executed only when
      widget_type is WE_X are executed even when widget_type is WE_W.
    */
    switch (wt)
    {
      case WE_W: 
        demo_do_something_for_WE_W();
      case WE_X: 
        demo_do_something_for_WE_X();
      default:
        /* Handle error condition */
        demo_report_error();
    }
}

この例には、break ステートメントがない case が 2 つあります。wtWE_W のとき、プログラムでは 2 つの case を中断しないでそのまま続行するため、WE_WWE_X のステートメントと default のケースが実行されます。default のケースまたは最後の case には break ステートメントが必要ないため、欠陥は報告されません。

修正 — コメントまたは break を追加

この例を修正するには、case ブロックの最後のステートメントとマークする次の case ブロックの間にコメントを追加して受け入れ可能なフォール スルーを文書化するか、break ステートメントを追加してフォール スルーを回避します。この例では、case WE_W はそのまま続行することを想定しているため、コメントを追加して明示的にこの動作を示します。2 つ目の case では、default ケースの続行を回避するため break ステートメントを追加します。

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

extern void demo_do_something_for_WE_W(void);
extern void demo_do_something_for_WE_X(void);
extern void demo_report_error(void);

void corrected_missingswitchbreak(enum WidgetEnum wt)
{
    switch (wt)
    {
      case WE_W:
        demo_do_something_for_WE_W();
        /* fall through to WE_X*/
      case WE_X:
        demo_do_something_for_WE_X();
        break;  
      default:
        /* Handle error condition */
        demo_report_error();
    }
}

結果情報

グループ: 適切な手法
言語: C | C++
既定値: オフ
コマンド ライン構文: MISSING_SWITCH_BREAK
影響度: Low

バージョン履歴

R2016b で導入

すべて展開する