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;
}

第一个只是为了避免使用关键字而重写的第二个goto,我认为该goto解决方案更具可读性。我花了一段时间,但我设法说服自己,gotos 并不总是邪恶的。

最后,如果可能的话,我更喜欢只使用if语句,因为它使代码更具可读性,但goto如果有必要的话。

于 2009-06-10T13:02:09.430 回答
4

我会说这不太可读。我认为使用 if 语句甚至 goto 将是一种更合适的方法。使用 goto 并不是世界末日,它完全可以接受并且适合错误处理。

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

于 2009-06-10T12:58:22.043 回答
0

我建议您使用while(true)而不是 switch:

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

另一种选择是将它包装在一个函数中并返回而不是中断。这通常是一个坏主意,因为它最终添加了不必要的抽象层。但是,在某些情况下,它可以使事情变得更简单。

于 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 回答