Main Content

Missing break of switch case

case block of switch statement does not end in a break, [[fallthrough]] or explanatory comment

Description

This defect occurs when a case block of switch statement does not end in a break, a [[fallthrough]], or a code comment.

If the last entry in the case block is a code comment, for instance:

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 assumes that the missing break is intentional and does not raise a defect.

Risk

Switch cases without break statements fall through to the next switch case. If this fall-through is not intended, the switch case can unintentionally execute code and end the switch with unexpected results.

Fix

If you forgot the break statement, add it before the end of the switch case.

If you do not want a break for the highlighted switch case, add a comment to your code to document why this case falls through to the next case. This comment removes the defect from your results and makes your code more maintainable.

In some cases, such as in template functions, the defect checker might ignore the comment at the end of a case statement. A cleaner way to indicate a deliberate fall through to the next case is to use one of these fallthrough attributes if possible:

  • [[fallthrough]]: Available since C++17.

  • [[gnu::fallthrough]] and [[clang::fallthrough]]: Available with GCC and Clang compilers.

  • __attribute__((fallthrough)): Available with GCC compilers.

Examples

expand all

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();
    }
}

In this example, there are two cases without break statements. When wt is WE_W, the statements for WE_W, WE_X, and the default case execute because the program falls through the two cases without a break. No defect is raised on the default case or last case because it does not need a break statement.

Correction — Add a Comment or break

To fix this example, either add a comment after the last statement in the case block and before the next case block to mark and document the acceptable fall-through or add a break statement to avoid fall-through. In this example, case WE_W is supposed to fall through, so a comment is added to explicitly state this action. For the second case, a break statement is added to avoid falling through to the default case.

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();
    }
}

Result Information

Group: Good Practice
Language: C | C++
Default: Off
Command-Line Syntax: MISSING_SWITCH_BREAK
Impact: Low

Version History

Introduced in R2016b

expand all