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

发布于 2024-10-06 20:45:10 字数 361 浏览 8 评论 0原文

我正在查看一段 C 代码,

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

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

I'm looking at a piece of C code which is along the lines of

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

I think that might be a problem, because printf might change errno between entering the function and reaching the switch. However, printf's manpage doesn't say anything about it setting errno, so can I assume it won't ever set it? Is there anything in the standards that guarantees which functions will and won't use errno?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

还在原地等你 2024-10-13 20:45:10

任何函数都可以设置 errno,但前提是将其设置为非零值。 ANSI C 规范规定:

程序启动时 errno 的值为零,但从未设置为
由任何库函数清零。* errno 的值可以设置为
无论是否存在错误,库函数调用都非零,
前提是 errno 的使用没有记录在
标准中的功能。

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

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

int localErrno = errno

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

Any function may set errno, but only if it is setting it to a non-zero value. The ANSI C spec states:

The value of errno is zero at program startup, but is never set to
zero by any library function.* The value of errno may be set to
nonzero by a library function call whether or not there is an error,
provided the use of errno is not documented in the description of the
function in the Standard.

*Thus, a program that uses errno for error checking should set it
to zero before a library function call, then inspect it before a
subsequent library function call.

So, if you are using errno the best practices approach is to set the value to 0 immediately before the library call that may fail and read it immediately after. In the case above it would be sufficient to add something like:

int localErrno = errno

immediately before the printf statement and use localErrno for your switch. This, of course, assumes that there are no library calls between the function that failed and your call to printerror. If there are you would need to store errno after the failed call and pass it in to your printerror function.

粉红×色少女 2024-10-13 20:45:10

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

In rare cases, printf can set errno. If you redirect stdout from your program to a file and the file system is full, printf() will return a negative number and set errno to ENOSPC (No space left on device). You should make a local copy of errno before calling printf().

野却迷人 2024-10-13 20:45:10

C99标准规定了以下内容:

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

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

The C99 standard specifies the following:

The value of errno is zero at program startup, but is never set to zero by any library function. The value of errno may be set to nonzero by a library function call whether or not there is an error, provided the use of errno is not documented in the description of the function in this International Standard.

So, in short, errno may be set by any library function. In order to determine if it actually is in a given case, standard practice is to set it to zero before calling the function in question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文