我可以假设C stdlib函数不使用errno吗?

我正在看一段C代码

void printerror(char *message) { printf ("There was an error: '%s'\n", message); switch (errno) { ... do stuff depending on errno } } 

我认为这可能是一个问题,因为printf可能会在进入函数和到达switch之间改变错误。 但是,printf的联机帮助页没有说出设置errno的任何内容,所以我可以假设它不会设置它吗? 标准中是否有任何内容可以保证哪些function将使用和不使用errno?

任何函数都可以设置errno,但仅当它将其设置为非零值时。 ANSI C规范声明:

程序启动时errno的值为零,但任何库函数都不会将其设置为零。*如果使用errno,则errno的值可以通过库函数调用设置为非零值,无论是否存在错误。未在标准中的function描述中记录。

*因此,使用errno进行错误检查的程序应在库函数调用之前将其设置为零,然后在后续库函数调用之前检查它。

因此,如果您使用的是errno,那么最佳实践方法是在库调用之前立即将值设置为0,这可能会失败并立即读取它。 在上面的情况下,添加类似的东西就足够了:

int localErrno = errno

紧接在printf语句之前,并使用localErrno作为您的开关。 当然,这假定在失败的函数和对printerror的调用之间没有库调用。 如果有,您需要在失败的调用后存储errno并将其传递给您的printerror函数。

在极少数情况下,printf可以设置errno。 如果将stdout从程序重定向到文件并且文件系统已满,printf()将返回一个负数并将errno设置为ENOSPC(设备上没有剩余空间)。 在调用printf()之前,您应该制作errno的本地副本。

C99标准规定如下:

程序启动时errno的值为零,但任何库函数都不会将其设置为零。 无论是否存在错误,errno的值都可以通过库函数调用设置为非零,前提是在本国际标准的函数描述中未记录errno的使用。

因此,简而言之, errno可以由任何库函数设置。 为了确定它是否确实在给定的情况下,标准做法是在调用相关函数之前将其设置为零。