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

时间:2011-06-24 06:37:26

标签: c error-handling

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

我想问一下是否应该使用errno / perror功能在运行时优雅地处理错误。我问这是因为MSVC使用它而Win32 api也大量使用它。我对gcc或'linux一无所知api'。今天gcc和MSVC都说errno / perror可以在多线程环境中安全使用。所以你的看法是什么?

感谢。

3 个答案:

答案 0 :(得分:7)

请注意,单独使用errno 是一个坏主意:标准库函数调用其他标准库函数来完成其工作。如果其中一个被调用的函数失败,errno将被设置为指示错误的原因,并且库函数可能仍然成功,如果它已经以它可以编程的方式编程回归其他机制。

考虑malloc(3) - 它可能被编程为首次尝试mmap(.., MAP_PRIVATE|MAP_ANONYMOUS)如果失败则回退到sbrk(2)以分配内存。或者考虑execvp(3) - 它可能在尝试执行程序时探测十几个目录,其中许多目录可能先失败。 “本地故障”并不意味着更大的故障。并且调用的函数在返回给你之前不会将errno设置回0 - 它可能具有从之前遗留下来的合法但不相关的值。

您无法简单地检查errno的值以查看是否遇到错误。如果涉及的标准库函数也返回错误返回,则errno 才有意义。 (例如来自NULL的{​​{1}}或来自getcwd(3)的{​​{1}},或来自-1的“负值”。)

但是在标准库函数失败的情况下,read(2)是发现为什么失败的唯一方法。当其他库函数(标准库未提供)失败时,它们可能会使用printf(3),或者它们可能提供类似但不同的工具(请参阅例如errnoerrno。)您将拥有检查您正在使用的库的文档以获取完整的详细信息。

答案 1 :(得分:1)

我不知道它是否真的是“应该”的问题,但如果您使用C语言进行编程并使用低级C / posix API,那么实际上没有其他选择。当然,如果这会冒犯你的风格敏感性,你可以把它包起来,但是它必须工作的方式(至少只要POSIX是一个标准)。

答案 2 :(得分:0)

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