【C言語】冗長コード
(duplicate,identical,redundant)

(style): Consecutive return, break, continue, goto or throw statements are unnecessary.

(スタイル):連続した return, break, continue, goto,文は不要です。
[(style)duplicateBreak]


■1.連続した return,break,continue,gotoは冗長です

int f(char *buf,int c){
    int     i ;
    for(i = 0; buf[i] != '\0'; i++){
        if(buf[i] == c){
            break   ;
            continue;//NG
        }
    }
    return  i ;
    return  i ;//NG
}

break直後のcontinueは
そもそも相反する単語なので
バグや無駄の可能性が高いです。

■2.同じ比較

(warning) Identical condition ‘x==1’, second condition is always false

警告:同じ比較をしているので2番目の比較は常に偽になる[(warning)identicalConditionAfterEarlyExit]

int f(int x)
{
    if(x == 1)  return  1;
    if(x == 1)  return  2;//間違い
    if(x == 3)  return  3;
    return  0;
}

if(x == 1)の比較を2回行っています。
1回目のif文が成立するとreturn するので、
2回目のif文が成立する事はありません。

■3.同じ両辺if(p->x!=0 && p->x!=0)

(style): Same expression on both sides of ‘&&’

(スタイル):&&演算子の両辺同じ
[(style)duplicateExpression]

enum    {OK=1,NG=2};
int f(const int ary[]){
    if(ary[0]>0 && ary[0]>0) return NG;//ダメ
    if(ary[0]>0 && ary[1]>0) return OK;
    return  0;
}
typedef struct {
    int x;
    int y;
} tag_t ;
int g(tag_t *p) {
    if(p->x!=0 && p->x!=0) return NG;//ダメ
    if(p->x!=0 && p->y!=0) return OK;
    return  0;
}
int h(int a,int b,int c,int d){
    if( a == 0 &&
        b == 0 &&
        c == 0 &&
        c == 0)//ダメ
        return  NG;
    return  d;
}

論理演算子の両辺が同じなので右辺の条件式に意味がありません。

■4.同じthen節とelse節

(style, inconclusive) Found duplicate branches for ‘if’ and ‘else’.

警告:then節とelse節が同じ
[(style)duplicateBranch]

//  cppcheck  --enable=all --inconclusive
typedef enum {same,diff} samediff_t ;
samediff_t f(int x,int y)
{
    if(x == y){
        return  same;
    } else {
        return  same;//NG:if文の意味がない
    }
}

then節とelse節が同じなのでif文の意味がありません。
この問題はthen節をコピーしてelse 節を作り、
else節の変更を忘れた時等に発生します。

cppcheck –enable=all だけでは警告が出ず
cppcheck –enable=all –inconclusiveで
警告が出ました。

■5.同一変数連続代入

(style): Variable ‘ret’ is reassigned a value before the old one has been used.

(スタイル):変数’ret’は古い値が使用される前に再設定された。
[(style)redundantAssignment]

extern int Sin(void),Cos(void);
int f1(void){
    int ret = 0; 
    ret = Sin() ;//警告されない
    return  ret ;
}
int f2(void) {
    int  ret;
    ret = 0 ; 
    ret = Sin() ;//警告されない
    return  ret ;
}
int f3(void) {
    int  ret ;
    ret = Sin() ; 
    ret = Cos() ;//★警告される
    return  ret ;
}

この cppcheck の警告は3行目、9行目のような
とりあえず0で初期化した変数に再設定しても警告は出ません。


16行目のようにretを上書きして何のためにSin()関数を呼んだのか不明なものだけ警告してくれます。