【问题标题】:Using errno for application / library error reporting使用 errno 进行应用程序/库错误报告
【发布时间】:2012-05-22 09:01:34
【问题描述】:

我正在为一个软件项目编写一个 C 库。我需要做一些错误报告,但我有点太懒了,无法实现我自己的一组复杂的错误代码、变量和函数。是否可以使用 libc 提供的 errno 工具进行自定义错误报告?我所有的错误都属于E... 宏给出的类别。

例如,假设我的代码包含一个以十六进制表示法读取 SHA256 哈希并将其转换为某种内部格式的函数。我想用errno报错:

#include <errno.h>

int hash_fromstr(hash_t *out, const char *in) {
  /* ... */

  if (strlen(in) != 65) {
    errno = EINVAL;
    return -1;
  }

  /* ... */
}

当然,这个例子被简化得非常荒谬,实际上在其他函数中可能会发生更多错误。

【问题讨论】:

  • 只要您的库可以发出标准错误代码而不会破坏errno 在链接到您的库的用户应用程序的其他部分的正常运行,我认为它没有问题。也许您可能会使用 errno 变量但不更改它并返回它的副本?
  • @Jim 我想将errno 用于库本身内部发生的错误 - 不一定在库调用的 libc 的函数中。
  • 那么你问是否可以设置errno 的值来向你的库的调用者报告错误?如果是这样,您可能想查看stackoverflow.com/questions/9856822/should-i-set-errno
  • @Jim 是的。这正是我想要做的。

标签: c errno


【解决方案1】:

您可以随意修改 errno 的值,只需确保您的库代码在这样做之前检查 errno 是否未设置,以确保您的库代码仍然可以正确检测导致设置 errno 的内部标准故障。您也可以查看"should I set errno" 了解更多信息。

【讨论】:

    【解决方案2】:

    是的,你可以修改它,它有线程作用域,这在那种错误处理中是非常可取的。

    使用 errno 错误系列 (E...) 并扩展它可能是一种非常强大但简单的错误处理模式。它可能被其他人认为是不好的方法,但恕我直言,它产生更清晰的代码和用于错误处理的标准化模式。

    【讨论】:

    • 如何扩展errno?据我所知,没有可移植的方法来找出哪些 errno 值未分配,即使您这样做了,您也会与尝试执行相同操作的其他库发生冲突。
    • @FUZxxl 确实不可能知道哪些值是未分配的,但是 int 类型范围足够大以容纳安全边距。关于冲突,我认为没有冲突发生,考虑到 errno 值仅具有单个函数调用的范围,因此,根据库,应仅针对库错误列表处理错误,避免冲突。你同意吗?
    • @fani 我不同意,因为将errno 用于自定义内容会破坏strerror 之类的内容——自定义errno 值在库调用失败后仍然存在,并且可能会扰乱外部处理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多