【问题标题】:C error handling coding-style [closed]C错误处理编码风格[关闭]
【发布时间】:2013-02-20 23:45:32
【问题描述】:

在以下代码结构的情况下:

int function_sequence(...)
{
    f1(...);
    f2(...);
    f3(...);
    f4(...);
    f5(...);
    return SUCCESS;
}

哪种错误处理方式更容易接受?

这个:

int function_sequence(...)
{
    if(f1(...)){
         // Error handling
         return ERROR;
    }

    if(f2(...)){
         // Error handling
         return ERROR;
    }

    ...

    return SUCCESS;
}

或者这个:

int function_sequence(...)
{
    if(f1(...)){
        goto error;
    }

    if(f2(...)){
        goto error;
    }

    ...

    return SUCCESS;

error:
    // Error handling
    return ERROR;
}

【问题讨论】:

  • 您可能需要针对 C 和 C++ 分别提出不同的问题,因为每个问题的错误处理习惯用法会非常不同。
  • 这是一道 c 题。 c++ 有更好的错误处理方式。第二个绝对不是c中的首选。 goto 是破坏的同义词。永远不要使用它。你有很多方法可以绕过它。
  • 我都见过。我最后一次看到 goto error 成语是公司强制编码风格。
  • @JoachimPileborg 即使在范围内,使用标志等是否比使用 goto 语句更好?
  • @Koushik 关于编码风格的所有问题,这是非常个人化的。除非别人要求,否则做你觉得最舒服的事。

标签: c error-handling coding-style


【解决方案1】:

对于 C,我更喜欢你的第二个选项。

此外,逐步清理(释放分配的内存等)很有用,就像在 Linux 内核中一样:

int function_sequence(...)
{
    if(f1(...)){
        goto error1;
    }

    if(f2(...)){
        goto error2;
    }

    ...

    return SUCCESS;

error2:
    cleanup2();

error1:
    cleanup1();

    // Error handling
    return ERROR;
}

【讨论】:

    【解决方案2】:
    int function_sequence(...)
    {
        if (f1(...) && f2(...) && f3(...)  && f4(...) && f5(...)) 
            return SUCCESS;
        else
            return ERROR;
    }
    

    【讨论】:

    • 这会使读取和调试变得复杂,因为您无法在单独的函数中设置断点。
    • 没错,但你可以在每个函数中设置断点,不是吗?
    【解决方案3】:

    在 C 中,我会使用第三个选项:

    int function_sequence(...)
    {
        bool ok = true;
        if (ok) ok = f1(...);
        if (ok) ok = f2(...);
        if (ok) ok = f3(...);
        if (ok) ok = f4(...);
        if (ok) ok = f5(...);
    
        if (!ok) error_handling();
    
        cleanup();  // Your example didn't have this, but it's often here.
    
        return ok ? SUCCESS : ERROR;
    }
    

    【讨论】:

      【解决方案4】:

      如果是异常情况导致函数无法工作,则抛出异常。

      如果你有理由坚持使用返回码,你可以使用

      if ( f1() && f2() && .... )
          return SUCCESS;
      else
          return ERROR;
      

      遇到第一个false0后会停止执行,所以效果和你的版本差不多。

      一些库在成功时返回 0(嘿,甚至 C++ 的 main 也会这样做)。所以你可能想要

      if ( !f1() &&.... )
      

      还是简单的

      return f1() && f2() &&.... ;
      

      【讨论】:

        【解决方案5】:

        这是我平时用的

        int function_sequence(...)
        {
            if(f1(...)){
                goto error1;
            }
        
            if(f2(...)){
                goto error2;
            }
        
            return SUCCESS;
        }
        
        error1:
            // Error 1 handling
            return -eerno1;
        
        error2:
            // Error 2 handling
            return -eerno2;
        
        //end of main
        

        【讨论】:

        • 这是有效的 C 代码吗?它粘贴的上下文是什么? main?我似乎无法弄清楚您是否在另一个过程(上下文)的主体内定义了 function_sequence 过程,或者这更像是一个具有一些有效 C 语法的伪代码。
        【解决方案6】:

        我喜欢做的方式是c语言中的以下内容:

        int function_sequence(...)
        {
            int res=0;
        
            if(f1(...)){
                goto ENDF;
            }
        
            if(f2(...)){
                goto ENDF;
            }
        
            ...
        
            res = 1;
        
        ENDF:
           if(res ==0)
           {
              //Error handling
           } 
        
           //Success and Error stuff to do (like free...).
        
            return res;
        }
        

        所以只有一个return,有时候两个都要做一些动作:error和success(比如free...)。

        我想我的观点可以讨论一下。

        【讨论】:

        • 即使所有调用都成功,此代码仍会调用错误处理。
        • 在错误标签上方添加return success。这将是正确的,虽然不是很好。
        • 我按照我的实际操作方式更改它...(复制/粘贴错误:/)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-06
        • 2019-10-12
        • 2015-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多