【问题标题】:C Error Checking FunctionC 错误检查功能
【发布时间】:2011-04-11 22:48:51
【问题描述】:

对于我的系统编程课,我们使用 C 进行了大量编程,并且由于我们目前正在学习使用 pthread 编程,因此需要对大多数功能进行错误检查。

我之所以说这不是真正的家庭作业,是因为它远远超出了这门课的预期。简单地单独检查每个功能就非常令人满意了。我只是觉得这是一种耗时且混乱的方法,并希望有一个更整洁的解决方案。

我想知道是否有人可以告诉我如何编写一个函数,该函数将任何 C 函数作为参数,然后是该函数所需的所有参数,以及所需的返回值(在这种情况下是正确的),并执行以下操作。

if(function_name(param1, param2, ...) != desired_return_value) {
    fprintf(stderr, "program_name: function_name() failed\n");
    perror("function_name(): ");
}

这可能吗?我们的课程几乎没有要求它,但让我很恼火的是,我编写的几乎所有函数都必须有 4 行代码来进行错误检查。它让人难以阅读。

即使是其他一些建议也会很好。我只是想增加可读性,所以如果这完全是错误的方向,一些正确的方向将不胜感激。

编辑:理想情况下,这应该在 gnu99 标准下编译:P

编辑 2:回应 James McNellis: 我们函数的错误不需要(我相信在这种情况下)需要处理。只需要提供通知。我们没有涉及处理线程/进程相关的错误(简而言之就是这个主题)。

【问题讨论】:

  • 嗯,这不是真正的家庭作业,但我不会说你没有说它不是。
  • 这些不是您不想要的机器人。
  • 根据我的经验,在很多情况下,尤其是在线程代码中,不处理错误肯定会导致早期秃顶、头痛和数小时的深夜调试。问题是在编写违反某些假设的代码和依赖它的代码之间很可能存在很长的延迟时间。

标签: c error-handling macros c-preprocessor variadic-functions


【解决方案1】:

在不使用宏的情况下用 C 编写通用代码并不是最简单的事情。

对于使用可变参数宏的(非常)基本的解决方案:

#define CALL_AND_CHECK(f, r, ...)                                \
    do {                                                         \
        if (f(__VA_ARGS__) != r)                                 \
        {                                                        \
            fprintf(stderr, "program_name: " #f "() failed\n");  \
            perror(#f "(): ");                                   \
        }                                                        \
    } while (0)

(请参阅Why are there sometimes meaningless do/while and if/else statements in C and C++ macros? 了解为什么使用“无意义”的 do/while 循环)

请注意,打印出错误消息而不实际处理错误几乎肯定是个坏主意。通常,不同的错误需要以不同的方式处理,所以像这样的通用代码可能不是特别有用。如果您不想尝试从这些错误中恢复,您可以exit(),这对于作业来说可能没问题,但在现实世界的程序中您不希望这样做。

【讨论】:

  • @James McNellis 我们已经对宏的坏处进行了大量讨论,但没有真正的理由。在什么情况下会出现问题?或者在使用宏之前我应该​​查找并注意哪些固有问题。
  • @Ben:这个宏表现得相当好:它对每个参数只求值一次,从而避免了宏可以做的一件令人惊讶的事情。您必须避免像这样使用它:if (condition) CALL_AND_CHECK(f,r,a,b,c) else CALL_AND_CHECK(f,r,x,y,z);,这不起作用,或者添加通常的宏 do/while(0) 技巧。宏的固有问题是它们看起来像函数调用,但实际上并非如此,它们只是文本替换,因此它们不会以非常直观的方式与 C 的语法进行交互。
  • 上面的宏确实应该有do..while(0)才能被称为行为良好。
  • @Arafangion - 不,这是为了确保它与分号一起正常工作(并且,例如,不“声称” am else 声明等)。
  • @Ben - 当然,但如果您使用do ... while(0) 形式,您(或其他任何人)将永远不必担心任意限制有效的 C 语法。但更重要的是,有时你会想“哦,我现在只输入一行if/else……”然后花两天时间调试一些看似奇怪的问题。 (无论如何,我真的只是想更正上面的断言,以帮助其他阅读它的人。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-30
  • 1970-01-01
  • 2014-09-24
  • 2012-11-06
  • 2011-08-13
  • 2019-07-27
  • 1970-01-01
相关资源
最近更新 更多