StackedCrooked
StackedCrooked

Reputation: 35535

Are consecutive calls to `errno` to be avoided?

Is it safe to call errno multiple times when dealing with the same error. Or is it safer to work with a local copy?

This sample illustrates my question:

// If recvfrom() fails it returns -1 and sets errno to indicate the error.
int res = recvfrom(...);
if (res < 0)
{
    // Risky?
    printf("Error code: %d. Error message: %s\n", errno, strerror(errno));

    // Safer alternative?
    int errorNumber = errno;
    printf("Error code: %d. Error message: %s\n", errorNumber, strerror(errorNumber));
}

Upvotes: 8

Views: 1092

Answers (5)

gpwclark
gpwclark

Reputation: 66

I was just looking into this myself and I think another function might be better suited to this problem, perror. perror is quite simple, for example if you malloc some memory and you want the sort of meaningful error message the strerror provides if malloc fails:

char **str_array = (char**) malloc(SOME_CONSTANT * sizeof(char*));
if (str_array == NULL){
    perror("malloc failed on str_array");
}

perror prints the string you typed, adds a space, then a semicolon, and then prints the human readable error text. It also doesn't seem to have the side effect that strerror does, unless I'm interpreting the man page incorrectly because it doesn't have a section for ERRORS: http://man7.org/linux/man-pages/man3/perror.3.html .

I'm also making successive calls that may fail, and perror seems like less lines of code and better syntax. However, I'm newer to C so please edit or delete if this information is inaccurate.

Upvotes: 0

Jens Gustedt
Jens Gustedt

Reputation: 78973

Generally nowadays errno is something much more complicated than a variable:

... errno which expands to a modifiable lvalue that has type int, the value of which is set to a positive error number by several library functions. It is unspecified whether errno is a macro or an identifier declared with external linkage. If a macro definition is suppressed in order to access an actual object, or a program defines an identifier with the name errno, the behavior is undefined.

E.g. in POSIX it is guaranteed to evaluate to something that is specific for the current thread. Thus it might have an access cost that is higher than for a simple variable.

So yes I would go for a local copy if performance is a concern, though I never benched this for real.

Upvotes: 1

Alex F
Alex F

Reputation: 43331

errno is variable and not function. Whan you use it, it cannot be reset. So, it is OK to use errno number of times, assuming that you don't call any function that can change/reset errno.

Upvotes: 1

Secure
Secure

Reputation: 4378

Any standard library function including printf and strerror is allowed to change errno, even if actually no error occurs:

7.5 3 The value of errno is zero at program startup, but is never set to zero by any library function. 170) 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.

Upvotes: 2

Habbie
Habbie

Reputation: 2230

The value of errno shall be defined only after a call to a function for which it is explicitly stated to be set and until it is changed by the next function call or if the application assigns it a value.

http://www.opengroup.org/onlinepubs/009695399/functions/errno.html

However, even strerror could theoretically count as a function call that can change it (see comment by schot) so you should, theoretically, still go with your save-first form.

Upvotes: 6

Related Questions