代码之家  ›  专栏  ›  技术社区  ›  0x6adb015

使用C switch语句进行错误处理

  •  0
  • 0x6adb015  · 技术社区  · 15 年前

    考虑这个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()

    5 回复  |  直到 15 年前
        1
  •  5
  •   Graeme Perrow    15 年前

    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 ,我认为 后藤 他们不是 总是 恶毒的

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

        2
  •  4
  •   Sweeney    15 年前

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

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

        3
  •  0
  •   Gordon Freeman    15 年前

    我建议你使用 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;
    }
    
        4
  •  0
  •   Brian    15 年前

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

        5
  •  -1
  •   Steve Melnikoff    15 年前

    另一种方法是使用级联ifs:

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

    等等不像其他一些方法那样有效,但避免了过度嵌套、goto、break、while(0)和多次返回。