我正在编写一个导出类似于send
和recv
接口的模块。
由于这些函数应分别返回发送和接收字节数,因此我不能像通常那样进行适当的错误管理(即使用枚举并返回助记值)。
在这种情况下,我应该像标准库一样设置errno
吗?如果是这样,由于errno
是线程特定的,是否有特定的写入方式,还是我可以简单地将值赋给它?
编辑:实验发现通过赋值设置errno
是有效的。但是:这对任何系统都是安全和可移植的吗?
在许多情况下,调用一些库函数时只有在将 errno
设置为零后才能可靠地检测到错误,所以不仅可以设置 errno
,而且应该这样做。请参见示例中的 strtol
。
来自 strtol
的 POSIX 规范:
[CX] [选项起始] 如果成功,则 strtol() 函数不会更改 errno 的设置。
由于在发生错误时返回 0、{LONG_MIN} 或 {LLONG_MIN} 和 {LONG_MAX} 或 {LLONG_MAX},而这些值也是成功的有效返回值,因此希望检查错误情况的应用程序应将 errno 设置为0,然后调用 strtol() 或 strtoll(),然后检查 errno。[选项结束]
实际上,你很可能可以进行“正确”的(正如你所说的)错误管理,因为你返回了一个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,其值由几个库函数设置为正数错误号。
errno
赋值,但请记住还有其他方法来表示错误,具体取决于你的情况,可能更合适:
int *
(或size_t *
或您使用的任何其他类型)的输出参数。然后可以返回错误代码。errno
被 POSIX 中几乎所有的函数使用(除了返回错误代码和一些奇怪的例外),而不仅仅是低级别的东西。 - R.. GitHub STOP HELPING ICE来源:http://support.sas.com/documentation/onlinedoc/sasc/doc700/html/lr1/errno.htm
errno
的唯一可移植值为EDOM
和ERANGE
因此,这回答了您的可移植性问题。
errno.h
中定义的枚举值。 - prelicEILSEQ
。 - paxdiablo
errno
和 C 标准,如果你想了解更多信息,请访问 https://dev59.com/RWcs5IYBdhLWcg3wUCYI (注:该链接为英文网站)。 - Nemo