处理相同错误时多次调用errno
是否安全。或者使用本地副本更安全吗?
此示例说明了我的问题:
// If recvfrom() fails it returns -1 and sets errno to indicate the error.
int res = recvfrom(...);
if (res < 0)
{
// Risky?
printf("Error code: %d. Error message: %s\n", errno, strerror(errno));
// Safer alternative?
int errorNumber = errno;
printf("Error code: %d. Error message: %s\n", errorNumber, strerror(errorNumber));
}
答案 0 :(得分:5)
只有在调用明确声明要设置的函数之后,才能定义errno的值,直到它被下一个函数调用更改或者应用程序为其赋值。
http://www.opengroup.org/onlinepubs/009695399/functions/errno.html
然而,即使strerror
理论上也可以算作可以改变它的函数调用(请参阅schot的评论),所以从理论上讲,你应该使用保存优先形式。
答案 1 :(得分:2)
包括printf和strerror在内的任何标准库函数都允许更改errno,即使实际上没有错误发生:
7.5 3程序启动时errno的值为零,但永远不会设置为 任何库函数都为零。 170) errno的值可以设置为 由函数调用非零 是否有错误, 如果没有使用errno 记录在描述中 这个国际的功能 标准。
答案 2 :(得分:1)
errno是可变的而不是功能。使用它时,无法重置。因此,可以使用errno次数,假设您没有调用任何可以更改/重置errno的函数。
答案 3 :(得分:1)
现在通常errno
比变量复杂得多:
... errno扩展为a 可修改的左值,类型为int, 其值设置为a 几个正误差数 库函数。它没有具体说明 errno是一个宏还是一个 用外部声明的标识符 连锁。如果是宏定义 为了访问而被压制 实际对象,或程序定义 名称为errno的标识符 行为未定义。
E.g。在POSIX中,它保证评估为特定于当前线程的东西。因此,它的访问成本可能高于简单变量。
所以是的,如果性能是一个问题,我会选择本地副本,尽管我从来没有真正想过这个。
答案 4 :(得分:0)
我自己只是在研究这个问题,我认为另一个功能可能更适合这个问题,perror。 perror非常简单,例如,如果你对某些内存进行malloc并且你想要一些有意义的错误消息,那么当malloc失败时,strerror会提供这些消息:
char **str_array = (char**) malloc(SOME_CONSTANT * sizeof(char*));
if (str_array == NULL){
perror("malloc failed on str_array");
}
perror打印您键入的字符串,添加空格,然后添加分号,然后打印人类可读的错误文本。它似乎也没有strerror所带来的副作用,除非我正确地解释了手册页,因为它没有错误的部分:http://man7.org/linux/man-pages/man3/perror.3.html。
我也在进行可能失败的连续调用,而perror似乎更少的代码行和更好的语法。但是,我比C更新,所以如果这些信息不准确,请编辑或删除。