0

実際の作業を行う前にエラーをチェックする次の C コンストラクトを検討してください。

int function(struct Context *context,struct Connection *conn)
{
    int retval;

    switch(0)
    {   
        case 0:
            retval = BUFFER_INACTIVE;
            if(conn->mSocket == -1) 
                break;
            retval = BUFFER_FULL;
            /* Is there enough room to add ? */
            if((context->mMaxBufferSize - conn->mSendPacketLength) < aPacketLength)
                break;

            /* Is the send packet buffer half sent? */
            if(conn->mSendPacketLength > 0 && conn->mSendPacketPos != conn->mSendPacket)
                break;

            /* Do some work here */
            retval = BUFFER_DONE;
    }
    /* Do some things before returning */
    printf("%d",retval);
    return retval;
}

これを読みやすいと思いますか?goto使用または積み重ねた代替案はif()より良いでしょうか?

4

5 に答える 5

5

スイッチソリューションを見たことはありませんが、次のようなことをしました:

do {
    err = func();
    if( err ) break;
    err = func2();
    if( err ) break;
    ...
} while( 0 );
if( err ) {
   // handle errors
}

しかし、それとこれの本当の違いは何ですか:

err = func();
if( err ) goto done;
err = func2();
if( err ) goto done;
...
done:
if( err ) {
   //handle errors;
}

1 つ目は 2 つ目のキーワードを使用しないように書き直したものであり、解決策はより読みやすくgotoなっていると思います。goto少し時間がかかりましたが、gotos が常に悪であるとは限らないことを自分自身に納得させることができました。

if最後に、コードが読みやすくなるため、可能であればステートメントのみを使用することを好みますがgoto、必要に応じて s を使用します。

于 2009-06-10T13:02:09.430 に答える
4

可読性が低いと言えます。if ステートメントや goto を使用する方が、はるかに適切なアプローチだと思います。goto を使用することは世界の終わりではなく、完全に受け入れられ、エラー処理に適しています。

http://kerneltrap.org/node/553/2131

于 2009-06-10T12:58:22.043 に答える
0

switch の代わりにwhile(true)を使用することをお勧めします。

while(true)
{   
            retval = BUFFER_INACTIVE;
            if(conn->mSocket == -1) 
                    break;
            retval = BUFFER_FULL;
            /* Is there enough room to add ? */
            if((context->mMaxBufferSize - conn->mSendPacketLength) < aPacketLength)
                    break;

            /* Is the send packet buffer half sent? */
            if(conn->mSendPacketLength > 0 && conn->mSendPacketPos != conn->mSendPacket)
                    break;

            /* Do some work here */
            retval = BUFFER_DONE;
            break;
}
于 2009-06-10T12:59:49.513 に答える
0

もう 1 つの方法は、関数でラップして、中断する代わりに返すことです。これは、不要な抽象化レイヤーを追加することになるため、多くの場合、悪い考えです。ただし、場合によっては、物事を簡単にすることができます。

于 2009-06-10T14:05:24.263 に答える
-1

別の方法は、カスケードされた if を使用することです。

u8 u8IsOk;

u8IsOk = Func1();

if(u8IsOk)
{
    /* Do some stuff...*/
    u8IsOk = Func2();
} /* if */

if(u8IsOk)
{
    /* Do some stuff...*/
    u8IsOk = Func3();
} /* if */

...等々。他のメソッドほど効率的ではありませんが、過剰なネスト、goto、break、while(0)、および複数のリターンを回避します。

于 2009-06-10T18:31:48.673 に答える