我应该设置errno吗?

Dac*_*cav 41 c errno

我正在编写一个导出类似于send和的接口的模块recv.

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

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

编辑:试验它我发现errno通过作业进行设置是有效的.仍然:这对任何系统都是安全和便携的吗?

gbu*_*mer 32

有点旧,但是错误 - 手册第3节说你可以直接分配它,即使它是一个宏,它将是线程局部的


Dan*_*ing 17

在许多情况下,您不仅可以设置errno,还可以设置errno.调用某些库函数时,如果首先设置errno为零,则只能可靠地检测到错误.请参阅strtol示例.

从POSIX规范strtol:

[CX] [Option Start]如果成功,strtol()函数不应更改errno的设置.

从0开始,{LONG_MIN}或{LLONG_MIN}和{LONG_MAX}或{LLONG_MAX}在出错时返回,并且在成功时也是有效返回,希望检查错误情况的应用程序应将errno设置为0,然后调用strtol()或strtoll(),然后检查errno.[选项结束]


pax*_*blo 8

实际上,你可能可以做"正确"(如你所说)错误管理,因为你返回一个int.

只需对读取或写入的字节数使用非负值,对错误代码使用负值.你不需要自己限定为-1:

enum myerrors {
    ERR_NO_MEMORY    = -1,
    ERR_BAD_ARGS     = -2,
    ERR_CPU_EXPLODED = -3,
    // and so on
};
Run Code Online (Sandbox Code Playgroud)

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

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


Jul*_*ter 6

您可以只指定一个值errno,但请记住,还有其他方法可以发出错误信号,根据您的情况,可能更合适:

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