warning: do not use ‘else’ after ‘return’
警告:return直後のelseは要らない
[readability-else-after-return]
■1.修正元ソース(非推奨)
char *f1(char *line){
if (!strchr(line, '/')) {
if (!strchr(line, '*')) {
return addid(1,line);
}
return addid(2,line);
}
return addid(3,line);
}
ぱっと見、何やってるか分からない。

■2.else を追加
char *f2(char *line){
if (!strchr(line, '/')) {
if (!strchr(line, '*')) {
return addid(1,line);
} else {
return addid(2,line);
}
} else {
return addid(3,line);
}
}
経路漏れが無いのはわかるが、
まだ何やってるか分かりにくい。

■3.条件を逆にして否定形!を使わない(やや推奨)
char *f3(char *line){
if (strchr(line, '/')) {
return addid(3,line);
} else {
if (strchr(line, '*')) {
return addid(2,line);
} else {
return addid(1,line);
}
}
}
否定形が無いほうが分りやすい。

■4.else if を使う
char *f4(char *line){
if (strchr(line, '/')) {
return addid(3,line);
} else if (strchr(line, '*')) {
return addid(2,line);
} else {
return addid(1,line);
}
}
だいぶ分りやすくなった。

■5.不要なelseを削除しよう!(推奨)
char *f5(char *line){
if (strchr(line, '/'))
return addid(3,line);
if (strchr(line, '*'))
return addid(2,line);
return addid(1,line);
}
不要な else を削除すると、
筆者でもわかる
単純明快な構造となった。

■6.まとめ(コンパイル可能な全コード)
#include <stdio.h>
#include <string.h>
#include <assert.h>
char *addid(int id,char *line);
//リファクタリング元ソース
char *f1(char *line){
if (!strchr(line, '/')) {
if (!strchr(line, '*')) {
return addid(1,line);
}
return addid(2,line);
}
return addid(3,line);
}
// else を追加
char *f2(char *line){
if (!strchr(line, '/')) {
if (!strchr(line, '*')) {
return addid(1,line);
} else {
return addid(2,line);
}
} else {
return addid(3,line);
}
}
//条件を逆にして否定形!を使わない
char *f3(char *line){
if (strchr(line, '/')) {
return addid(3,line);
} else {
if (strchr(line, '*')) {
return addid(2,line);
} else {
return addid(1,line);
}
}
}
// else if を使う
char *f4(char *line){
if (strchr(line, '/')) {
return addid(3,line);
} else if (strchr(line, '*')) {
return addid(2,line);
} else {
return addid(1,line);
}
}
// else を使わない
char *f5(char *line){
if (strchr(line, '/'))
return addid(3,line);
if (strchr(line, '*'))
return addid(2,line);
return addid(1,line);
}
int main(void){
char *input = "/usr/include/stdio.h";
FILE *fp = fopen(input,"re");
char buf[BUFSIZ];
while(fgets(buf,BUFSIZ,fp) != NULL){
char *s1 = f1(buf);
char *s2 = f2(buf);
char *s3 = f3(buf);
char *s4 = f4(buf);
char *s5 = f5(buf);
printf("%s",s1);
if(strcmp(s1,s2)!=0) assert(0);
if(strcmp(s1,s3)!=0) assert(0);
if(strcmp(s1,s4)!=0) assert(0);
if(strcmp(s1,s5)!=0) assert(0);
}
fclose(fp);
}
//行頭にID追加
char *addid(int id,char *line){
static char buf[BUFSIZ];
sprintf(buf,"%d:%s",id,line);
return buf ;
}
f1()関数~f5()関数まで
やってる事は皆同じである事を
検証するプログラムです。
筆者はf5()関数が一番わかりやすのですが、
皆さんはどれが一番わかりやすいですか?