【问题标题】:Do you recommend using errno in new C APIs?你推荐在新的 C API 中使用 errno 吗?
【发布时间】:2011-04-23 11:20:38
【问题描述】:

您是否建议在新的 C API 中使用 errno?

是否应该改用http://developer.gnome.org/glib/stable/glib-Error-Reporting.html 等其他报告问题的方法?

你有什么推荐的?

【问题讨论】:

    标签: c api errno


    【解决方案1】:

    errno 应保留给 C 标准库,程序应将其视为只读值。

    编写新代码我强烈反对使用 errno 样式的全局变量来检查错误代码。假设你有函数ab 通过ab_error 报告它们的状态,那么你必须这样写:

    a();
    if( ab_error == AB_NOERROR ) {
        b();
        if( ab_error == NO_ERROR ) {
            /* ... */
        }
    }
    

    您看,您很快就会堆积嵌套级别。但是,如果您的函数返回错误代码,您可以这样写:

    int error_a;
    int error_b;
    
    if( (error_a = a()) == A_NOERROR
     && (error_b = b()) == B_NOERROR
    ){
        /* ... */
    } else {
        /* test the error variables */
    }
    

    您甚至可以像这样链接多个错误条件:

    int error_a;
    int error_b;
    int error_c;
    
    if( (error_a = a()) == A_NOERROR
     &&  ( (error_b = b()) == B_NOERROR
        || (error_c = c()) == C_NOERROR )
    ){
        /* ... */
    } else {
        /* test the error variables */
    }
    

    这比将整个内容分散在几个嵌套的 if 语句中更具可读性。

    【讨论】:

    • errno 不应被视为只读。 c库中的某些函数(例如strtol、strtod)只有调用者在调用之前清除errno才能检测到错误。
    • @William:当然,但我的意思是:不要用它来传递你自己的错误代码。
    【解决方案2】:

    您总是可以问自己,全局errno 在具有多线程(或不包含单独的全局变量副本的其他形式的并发)的程序中工作得如何。典型的结论可能是“不太好”,因此其他解决方案可能更可取。

    【讨论】:

    • 它不是“全局的errno”,而是“全局的errno”,它的定义不是extern int,而是一个扩展为的宏int 类型的左值,正是因为它需要特定于线程。
    • @R.:感谢您的评论,您是对的。我的陈述是基于在明显不合规平台上的经验,在这些平台上errno 的要求行为并不总是得到遵守。
    • +1 因为它强调了“全局变量”的邪恶,尽管 errno 不完全是一个全局变量;但是,我的man errno 说“errno 可能是一个宏。errno 是线程本地的”,而不是它肯定是一个宏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 2011-08-01
    • 1970-01-01
    相关资源
    最近更新 更多