Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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().

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top