The first piece of code is simply incorrect, and I will explain why later, but first we need a little background.
errno is a local stream variable. If the system call or some library functions fail, a non-zero value is set. It remains unchanged when a system call is successfully completed. Thus, it always contains the error number of the last failed call.
This means that you have two options. Either set errno to 0 before each call, or use the standard idiom for errno . Here's the pseudo code for the standard idiom
if ( foo() == some_value_that_indicates_that_an_error_occurred ) then the value in errno applies to foo else foo succeeded and the errno must be ignored because it could be anything
Most programmers will use the standard idiom, because setting errno to 0 before each system call is annoying and repeated. Not to mention that you can forget to set errno to 0 in one place, this is really important.
Return to the first code snippet. This is not true because there is no return value from strtol that uniquely points to strtol . If LONG_MAX returns LONG_MAX , an error may have occurred or the line really contained the LONG_MAX number. There is no way to find out if the call to strtol unsuccessful. This means that the standard idiom (which the first piece of code is trying to implement) cannot be used with strtol .
To use strtol correctly you need to set errno to 0 before calling like this
errno = 0; result = strtol( buffer, &endptr, 10 ); if ( errno == ERANGE ) {
Note that some implementations define other nonzero values for errno . See the corresponding man page for details.
source share