【问题标题】:Concise and non-obtrusive error handling in CC 中简洁且不显眼的错误处理
【发布时间】:2013-12-13 16:00:19
【问题描述】:

Error handling in C code

#define CHECK_FOR_ERRORS(ret)                           \
    if(ret != CY_U3P_SUCCESS)                           \
    {                                                   \
        handleCriticalError(ret, __FILE__, __LINE__);   \
    }

预期用途:

CHECK_FOR_ERRORS(CyU3PPibInit(CyTrue, &pibClock));

没有返回变量,没有额外的代码行,只用这个宏包装重要的函数调用。

但它不起作用。该宏不评估函数调用,它只将函数指针转换为int。

我该如何进行这项工作?

【问题讨论】:

  • 宏在编译时运行,因此它们从不评估函数调用。您应该将宏视为由预处理器扩展的精美文本替换设备。
  • @hetepeperfan,我可以用函数来做到这一点吗?有什么?

标签: c error-handling


【解决方案1】:

您的宏调用该函数两次,第一次是实际调用,一次是错误处理调用。试试这个:

#define CHECK_FOR_ERRORS(ret)                           \
    do { int r = ret; if (r != CY_U3P_SUCCESS) {\
    handleCriticalError(r, __FILE__, __LINE__);   \
    } while(0)

您可以使用 gcc 的 -E 标志或编译器的类似标志来查看宏是如何解释的。而且一般情况下,尽量在宏定义中每个宏参数只使用一次,以防止出现此类问题。

【讨论】:

  • 我觉得效果很好!我正在替换一个更冗长的错误报告方案,并且代码大小减少了一半!
【解决方案2】:

我个人会更容易做到这一点。假设CyU3PPibInit(CyTrue, &pibClock) 初始化了一些库,如果成功则返回 0。我会做如下的事情:

if ( CyU3PPibInit(CyTrue, &pibClock) != 0){
    fprintf(stderr, "At %s : %d: unable to load CyU3PPibInit, ", __FILE__, __LINE__);
    /*eiter abort here or sets some variable that your subsequent program flow doesn't use  this library */
}
/*continue without the library*/

这样您就可以轻松理解代码。 Marco 替换使代码通常难以阅读。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-30
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 2017-10-25
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多