【C言語】
早期リターン(early return)と
時代遅れの関数出口1つの比較

■この記事の概要

この記事では、C言語の「早期リターン」と「関数の出口を1つに限定する」コーディング規約の比較を行っています。早期リターンがコードの可読性を高める一方、出口1つの方針は深いネストや複雑化を招く非推奨の手法として例示されます。効率的で読みやすいコードを書くために早期リターンを推奨しています。

■早期リターンは読みやすい(推奨)

#include <stdio.h>
//推奨する:早期リターン
int get_volume(int x,int y,int z){
    if(x <= 0)
        return -1;
    if(y <= 0)
        return -1; 
    if(z <= 0)
        return  -1;
    return x * y * z;//体積を求める 
}
int main(void){
    printf("体積=%d\n",get_volume(2,3,4));
}

コーディング規約 「関数の出口1つだけ」を
強要するプロジェクトは多いです。

しかしこのルールを守った読みやすいコードを
見たことがありません。

規約を強要する人は是非ともリーダブルコードを読んで欲しい。

以下にルールを守って難解になったコードの例を示します。


■ネストを深くし出口1つを厳守(非推奨)

#include <stdio.h>
//ネストを深くして出口1つだけを死守する
int get_volume(int x,int y,int z){
    int volume = 0 ;
    if(x > 0)
        if(y > 0)
            if(z > 0)
                volume = x * y * z;//体積を求める
            else
                volume = -1;
        else
            volume = -1;
    else 
        volume = -1;
    return  volume ; 
}
int main(void){
    printf("体積=%d\n",get_volume(2,3,4));
}

深いネストは理解しにくいので非推奨です。

条件をひっくり返して
早くreturnするとネストが浅くなります。


■do-while(0)で出口1つを厳守(非推奨)

#include <stdio.h>
//do-while(0)を使い出口1つだけを死守する
int get_volume(int x,int y,int z){
    int ret = 0;
    do {
        if(x <= 0){
            ret = -1;
            break;
        }
        if(y <= 0){
            ret = -1;
            break;
        }   
        if(z <= 0){
            ret = -1;
            break;
        }
        ret = x * y * z;//体積を求める
    } while(0);           
    return  ret;
}
int main(void){
    printf("体積=%d\n",get_volume(2,3,4));
}

do-while(0)構文によって
ネストが深くなるので非推奨です。


■フラグを使い出口1つを厳守(非推奨)

#include <stdio.h>
//フラグを使い出口1つだけを死守する
enum {OK=0,NG=-1};
int get_volume(int x,int y,int z){
    int ret = OK;
    if(ret == OK){
        if(x <= 0){
            ret = NG;
        }
    }
    if(ret == OK){ 
        if(y <= 0){
            ret = NG;
        }   
    }
    if(ret == OK){ 
        if(z <= 0){
            ret = NG;
        }
    }
    if(ret == OK){
        ret = x * y * z;//体積を求める
    }
    return  ret;
}
int main(void){
    printf("体積=%d\n",get_volume(2,3,4));
}

フラグの状態を注意する必要があるので
非推奨です。


アンケート

16
貴方のエラー処理のスタイルは