今天应该使用errno/perror方法来检测错误吗?

3

我知道之前有很多关于C语言中错误处理的问题,但这个问题是关于errno的。

我想问一下,在运行时我们是否应该使用errno/perror功能来优雅地处理错误。我问这个问题是因为MSVC使用它,而Win32 API也大量使用它。我不知道gcc或“linux API”的情况。今天,无论是gcc还是MSVC都表示,在多线程环境下可以安全地使用errno/perror。那么你的看法是什么?

谢谢。


3
你会一直问这个问题,直到得到你想要的答案吗? - David Heffernan
可能是使用用户定义的错误代码和errno?的重复问题。 - David Heffernan
@David:不,已经结束了,对sarnold的回答感到满意... - rsjethani
3个回答

7
请注意,仅使用errno是一个不好的主意:标准库函数调用其他标准库函数来完成它们的工作。如果其中一个被调用的函数失败了,errno将被设置为指示错误原因,并且库函数可能仍然成功,如果它已经以一种可以回退到其他机制的方式编程。
考虑malloc(3) - 它可能被编程为首先尝试mmap(.., MAP_PRIVATE|MAP_ANONYMOUS),并且如果失败则回退到sbrk(2)来分配内存。或者考虑execvp(3) - 在尝试执行程序时,它可能探测十几个目录,其中许多可能会先失败。'局部失败'并不意味着更大的失败。而且在返回给您之前,您调用的函数不会将errno设置回0 - 它可能具有合法但无关紧要的早期值。
您不能简单地检查errno的值,以查看是否遇到了错误。只有当涉及的标准库函数也返回错误返回值时,errno才有意义。(例如从getcwd(3)返回NULL或从read(2)返回-1,或从printf(3)返回“负值”。)
但是在标准库函数失败的情况下,errno是发现它们失败的唯一方法。当其他库函数(不由标准库提供)失败时,它们可能使用errno或提供类似但不同的工具(例如ERR_print_errors(3ssl)gai_strerror(3))。您必须查看您正在使用的库的文档以获取完整的详细信息。

那么,如何检测标准库函数和内部标准库函数中的错误呢?顺便说一句,感谢您的帖子,非常有帮助。 - Cool_Coder
1
@CAD_coding,遗憾的是,在检查标准库函数的错误方面没有“简单”的方法——对于您使用的每个函数阅读手册页面,查看“返回值”部分以发现错误返回(有时为“0”,有时为“-1”,有时为“NULL”),并编写代码来检查错误。只有在出现错误返回的情况下,errno才有意义。 - sarnold

1
我不知道这是否真的是一个“应该”的问题,但如果您正在使用低级C/POSIX API进行C编程,那么实际上没有其他选择。当然,如果这种方法冒犯了您的风格感,您可以对其进行封装,但在底层,它必须按照这种方式工作(至少在POSIX仍是一项标准的情况下)。

0
在Linux中,errno可以在多个线程或进程中安全地读写,但不能与perror()一起使用。它是一个不可重入的标准库。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接