【问题标题】:Should I set errno?我应该设置errno吗?
【发布时间】:2012-04-09 01:16:40
【问题描述】:

我正在编写一个模块,它导出类似于sendrecv 的接口。

由于这些函数应该分别返回发送和接收的字节数,因此我无法像往常那样进行适当的错误管理(即使用枚举并返回助记符值)。

在这种情况下,我应该像标准库那样设置errno 吗?如果是这样,由于errno 是特定于线程的,是否有特定的书写方式,或者我可以简单地为其赋值?

编辑: 试验它我注意到通过分配设置errno 是有效的。仍然:这对于任何系统来说都是安全且便携的吗?

【问题讨论】:

标签: c errno


【解决方案1】:

这有点老了,但是errno - manual section 3 说你可以直接赋值给它,即使它是一个宏,它会是线程本地的

【讨论】:

    【解决方案2】:

    不仅可以设置errno,在很多情况下你应该设置errno。调用某些库函数时,只有先将errno 设置为零,才能可靠地检测到错误。 See strtol for an example.

    来自strtol的POSIX规范:

    [CX] [Option Start] strtol()函数成功后不会改变errno的设置。

    由于 0、{LONG_MIN} 或 {LLONG_MIN} 以及 {LONG_MAX} 或 {LLONG_MAX} 在错误时返回并且也是成功时的有效返回,因此希望检查错误情况的应用程序应将 errno 设置为 0,然后调用strtol() 或 strtoll(),然后检查 errno。 [选项结束]

    【讨论】:

      【解决方案3】:

      实际上,您可能可以进行“正确”(如您所说)错误管理,因为您返回了 int

      只需对读取或写入的字节数使用非负值,对错误代码使用负值。你没有将自己限制在-1

      enum myerrors {
          ERR_NO_MEMORY    = -1,
          ERR_BAD_ARGS     = -2,
          ERR_CPU_EXPLODED = -3,
          // and so on
      };
      

      但是,以您想要的方式设置errno 是有效的。标准规定 errno 扩展为可修改的左值,这意味着您可以设置它。来自C1x/n1425, 7.5 Errors <errno.h>

      ... 和 errno 扩展为具有 int 类型的可修改左值,其值由多个库函数设置为正错误数。

      【讨论】:

        【解决方案4】:

        您可以只为 errno 分配一个值,但请记住,还有其他方法可以发出错误信号,根据您的具体情况,这些方法可能更合适:

        1. 不返回读取的字节数,而是使用类型为int *(或size_t * 或您使用的任何类型)的输出参数。然后您可以返回错误代码。
        2. 假设您的返回类型是有符号类型,并且发送或接收的字节数为负数没有意义,请使用负值来表示相应的错误情况。

        【讨论】:

        • errno 几乎被 POSIX 中的所有函数使用(除了返回错误代码和一些奇怪异常的函数),而不仅仅是低级的东西。
        【解决方案5】:

        是的,您可以分配给它,是的,分配将是线程安全的。见Is errno thread-safe?

        【讨论】:

          【解决方案6】:

          发件人:http://support.sas.com/documentation/onlinedoc/sasc/doc700/html/lr1/errno.htm

          errno 的唯一可移植值是 EDOMERANGE

          这样就回答了您的可移植性问题。

          【讨论】:

          • 我对分配它的技术细节更感兴趣,但我没想到会出现这种可移植性问题! :)
          • @Dacav - 我不认为你有任何特殊的设置方法......你可以分配给它......我会使用errno.h中定义的给定枚举值如果可能的话。
          • 该列表并不完整,EILSEQ 是标准规定的。
          • @prelic 我关于设置它的问题来自于它是一个使用宏实现的特定于线程的全局变量。枚举值 +1(如果您想要有意义的值,这当然是绝对需要的!)
          • @R.. 当我阅读更多内容时,我发现...不确定那篇文章是过时的还是错误的。
          猜你喜欢
          • 2015-10-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-10
          • 2017-03-11
          • 1970-01-01
          相关资源
          最近更新 更多