【问题标题】:Function that return an error if it fails [closed]如果失败则返回错误的函数[关闭]
【发布时间】:2016-04-10 12:45:38
【问题描述】:

我想知道以下哪种解决方案最好,为什么。

解决方案 1

bool foo(void)
{
   if (is_true())
      return true; // Error
   else
      return false; // No error
}

解决方案 2

bool foo(void)
{
   if (is_true())
      return false; // Error
   else
      return true; // No error
}

解决方案 3

int foo(void)
{
   if (is_true())
      return -1; // Error
   else
      return 0;  // No error
}

解决方案 4

size_t foo(void)
{
   if (is_true())
      return SIZE_MAX; // Error
   else
      return 0;  // No error
}

有人会说一个名为is_raining() 的函数应该在不下雨的时候返回false,但是bash 一个返回0 的程序意味着成功。负值通常被认为是错误,但是我怎么知道我应该如何处理我的返回码?

if(foo())
   printf("Error\n");

if(!foo())
   printf("Error\n");

if(foo() < 0)
   printf("Error\n");

【问题讨论】:

  • 这是上下文问题。就像你说的,像is_raining 这样的函数在下雨时应该返回true,否则返回false,但是对于像calculate_some_number 这样的函数返回true 或false 是没有意义的。但是,如何从返回布尔值的函数中返回错误?在 C 中,传统方法是返回 int 并使用 0 表示“假”,1 表示“真”,-1 表示“错误”。最后,这取决于你,主要是你记录它,并且你是一致的。
  • 和一个名为 is_sunny_day 的函数在下雨时不应该返回 true - 您选择的 foo() 并没有真正告诉我们它应该返回什么;一个'foo',也许?如果&lt;condition&gt; 为真,则名为is_&lt;condition&gt; 的函数应该返回一个非零值——因为这样你就可以编写if——像if (is_raining()){...} 这样的语句。
  • 另外,您的所有示例仅返回 两个 案例 - 某些情况是真的,或者发生了错误。在现实生活中,几乎总是有三个——is_raining() 可能需要返回 truefalse 和“不知道,百叶窗关闭”
  • 没有一个选项可以被认为是“最好的”或实际上是“最差的”,因为没有一个选项适用于所有功能。主要考虑的是错误值必须与任何有效的返回值区分开来。

标签: c error-handling


【解决方案1】:

您可以使用的另一种方法是向函数传递一个指向错误结构的指针,例如:

struct{
    int errorcode;
    char* errormessage;
} typedef Error_Structure;

void foo(Error_Structure* error){
      if(is_True()){
          error->errorcode = 1;
          error->errormessage = "it was true!";
          return;
      }
}

int main(void){
    Error_Structure error;
    foo(&error);
    if(error->errorcode != 0){
         printf(error->errormessage);
    }
}

这样,对于更复杂的应用程序,对于 foo 函数,错误代码可以更便于开发人员和最终用户排除错误。

【讨论】:

  • 我很惊讶 struct{ int errorcode; char* errormessage; } typedef Error_Structure; 编译。通常的方式是typedef struct { int errorcode; char* errormessage; } Error_Structure;。顺便说一句,error 未初始化,您从函数 = UB 中取消引用它。
  • 糟糕,不要过多地使用 C,我更熟悉看到最后的 typedef。但是,是的,取消引用是愚蠢的。所以应该在main函数中:Error_Structure error;foo(&error);
  • 我建议editing your answer纠正错误。
【解决方案2】:

我更喜欢整数作为返回码。这是大多数函数在 C 中所做的。 这样功能是可扩展的,可以添加更多的错误码。

使用该功能的代码可以选择:

  • 将所有错误代码视为相同,例如仅打印“错误”(返回值

  • 更精细的错误处理,测试所有错误代码。

【讨论】:

  • 扩展这个答案,我在 NI 软件中看到的一个技巧是安装一个文件,该文件提供基于整数错误代码的描述。然后,您可以在不重新编译代码的情况下更新此文件,并根据需要更新错误描述。
【解决方案3】:

在我看来,这是你的选择。如果您认为某些函数应该在错误时返回 false,请让它这样做。

例如:

bool valid() {
    if (1 == 1) return true;
    return false;
}

if (not valid()) { // clear enough, eh?
    /* do something */
}

如果你的函数应该在出错时返回一个负值,让它这样做。

int sqrt(int x) {
    if (x < 0) return -1;
    // do something and return a valid value 
}

所以你知道sqrt 不能是负数,然后明白如果你得到-1,那就是一个错误。

你也可以返回true如果你愿意

bool ErrorOccurred() {
    if (errno == 5) return true;
    return false;
}

if (ErrorOccurred()) { // very easy to understand
    puts("There was an error!");
} else {
    puts("Everything is OK");
}

【讨论】:

    【解决方案4】:

    嗯,我认为这是你喜欢什么的问题。但在我看来,真假是暗示 C 中错误的最佳方式(除非你想在 C++ 中工作,它以异常的形式有更好的错误处理)。

    您可以使用解决方案 2,然后:

    if(!foo())
       printf("Error\n");
    

    可能是最容易理解的。无论您使用哪种程序,程序的速度都没有区别,因此基本上您只是在考虑最简单且组织良好的代码。 另外,如果你想使用 bool,这意味着你需要包括:

    #include <stdbool.h> 
    

    【讨论】:

      猜你喜欢
      • 2020-03-22
      • 1970-01-01
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      • 2015-08-11
      • 1970-01-01
      • 2018-04-20
      • 2021-09-24
      相关资源
      最近更新 更多