Why to set errno to zero at the time of initialization of the program and can't test it before error occurred?

7,875

Solution 1

By convention we check the errno variable only when there is an error occurred (like some of the function returned with -1).

Question 1 : Then what is the use of setting errno to 0 before starting the program.

Indeed we should only check errno in the case where an error occurred. This is because if no error occurred, then it is still possible that errno will contain a non-zero value (e.g. if an error occurred during the execution of a library call but the error was recovered).

As such, setting errno to 0 before "starting the program" is not necessary, and I wouldn't follow that advice.

More, I read that it is better to store the error number to the local variable and then to check it

Yes! Your observation about printf() being able to clobber errno is correct. If its value needs to be preserved, it should be copied to a local variable as soon as possible after the error occurs.

Question 2 : Does the above statement applies to perror() and strerror() , because they are also system calls , and there is possibility that the error occurred with them too.

perror() probably doesn't call anything that modifies errno, but if it does then it must be careful to copy the value of errno before that happens. I'm sure you can assume that perror() works correctly on your system!

strerror() doesn't need to worry about that because it takes the error number as a parameter, so even if where to clobber errno the previous value has already been saved.

In Advanced Programming in the UNIX Environment by Richard Stevens , I read that we should examine the value of errno, only when the return value from a function indicates that an error occurred. I do not understand why ?

Because system calls and library calls that set errno on failure are not required to set it on success, so it retains whatever value it had before.

Solution 2

Answer to question 1, why should we set errno to 0 at the beginning of the program is that at some time some idiot may modify the program and use the errno value without checking that the previous system call failed (errno is only set upon failure, it's not reset to 0 on success).

perror() and strerror() are not system calls, they're library functions. They will take care to preserve the original value of errno at the time they're called. (Actually strerror() may be a macro (#define) so it should only be called when you know errno has a valid value.)

Share:
7,875

Related videos on Youtube

munjal007
Author by

munjal007

Updated on September 18, 2022

Comments

  • munjal007
    munjal007 over 1 year

    I am reading the material available on errno variable of <errno.h> header file.

    I read :

    " A value of 0 indicates that there is no error in the program." and "As a good practice, developer should set errno to 0 at the time of initialization of the program"

    By convention we check the errno variable only when there is an error occurred (like some of the function returned with -1).

    Question 1 : Then what is the use of setting errno to 0 before starting the program.

    More, I read that it is better to store the error number to the local variable and then to check it , i.e.

     if (somecall() == -1) {
          printf("somecall() failed\n");
          if (errno == ...) { ... }
          }
    

    In above code it is possible that printf() function call can overwrite the value of errno , if some error occurs with printf().

    Question 2 : Does the above statement applies to perror() and strerror() , because they are also system calls , and there is possibility that the error occurred with them too.

    In Advanced Programming in the UNIX Environment by Richard Stevens , I read that we should examine the value of errno , only when the return value from a function indicates that an error occurred. I do not understand why ?

  • Stéphane Chazelas
    Stéphane Chazelas almost 6 years
    perror() is not a system call but unless something has explicitly requested buffering on stderr, it calls the write() system call that will set errno upon failure to write on fd 2. That shouldn't affect what message it tried to display as that would happen after the message has been prepared.