【C言語】 /*fallthrough*/ switch文でbreakしない時の
残念なコメントの書き方

転落 Fallthrough

warning: this statement may fall through

警告:多分 break忘れ(フォールスルー)
[-Wimplicit-fallthrough=]

■break忘れの例

#include    <stdio.h>
void    f(int 親,int 子){
    switch(親)    {
    case    1:
        switch(子) {
        case    101:
        case    102:
        case    103:
        case    104:
            printf("子のswitch\n");
            break ;
        }

    case    2:
    case    3:
    case    4:
        printf("親のswitch\n");
        break ;
    }
}

switch文がネストしている場合子供のswitchのbreak を書いて、
それで安心して、
親のswitchのbreak を忘れる場合がよくあります。


■意図的にbreakしない時の推奨コメント

#include    <stdio.h>
void    f(int 親,int 子){
    switch(親)    {
    case    1:
        switch(子) {
        case    101:
        case    102:
        case    103:
        case    104:
            printf("子のswitch\n");
            break ; 
        }
        //fall through  
    case    2:
    case    3:
    case    4:
        printf("親のswitch\n");
        break ;
    }
}

意図的にbreakしない場合
/* fall through */などのコメントを
通常 break を記述する場所に書きます。


■連続した空のcaseにコメントは不要

#include    <stdio.h>
void    f(int 親,int 子){
    switch(親)    {
    case    1:
        switch(子) {
        case    101://fall through
        case    102://fall through
        case    103://fall through
        case    104://fall through
            printf("子のswitch\n");
            break ; 
        }

    case    2:
        //fall through
    case    3:
        //fall through
    case    4:
        printf("親のswitch\n");
        break ;
    }
}

連続した空のcaseにわざわざコメントを書く必要はありません。


■caseの上にコメントを書かないで

#include    <stdio.h>
void    f(int 親,int 子){
    switch(親)    {
    case    1:
        //fall through
        switch(子) {
        case    101:
        case    102:
        case    103:
        case    104:
            printf("子のswitch\n");
            break ;
        }

    case    2:
    case    3:
    case    4:
        printf("親のswitch\n");
        break ;
    }
}

case文の上部にコメントを書かないで下さい。


■caseの横にコメントを書かないで

#include    <stdio.h>
void    f(int 親,int 子){
    switch(親)    {
    case    1:
        switch(子) {
        case    101:
        case    102:
        case    103:
        case    104:
            printf("子のswitch\n");
            break ;
        }

    case    2:  //fall through
    case    3:
    case    4:
        printf("親のswitch\n");
        break ;
    }
}

case文の横にコメントを書かないでください


■break忘れと断言できる時

(warning): Variable ‘ret’ is reassigned a value before the old one has been used. ‘break;’ missing?

警告:break が無いので変数 ret を上書きする

[(warning)redundantAssignInSwitch]

int f1(void),f2(void),f3(void),f4(void);
int  f(int x,int y){
    int     ret = 0 ;
    switch(x){
    case    1:  f1();   //意図的かも?
    case    2:  f2();   break ;
    case    3:  f3();   break ;
    default:    f4();   break ; 
    }
    switch(y){
    case    5:  ret = 5;//確実にbreak忘れ    
    case    6:  ret = 6;    break ;
    case    7:  ret = 7;    break ;
    default:    ret = 8;    break ; 
    }
    return  ret;
}

case 1はbreak を忘れたのか意図的なのか判断できませんが
case 5はbreakが無いとret=5をret=6に上書きするので
break を忘れたと断言できます。

参考:

CWE-484: Omitted Break Statement in Switch

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