* * * * *

          I think Mac OS-X is wrong in this case, and Linux is right

There was apparently a frantic bug-hunt involving “Project: Lumbergh [1]”
yesterday that I was not involved in. From the description of the bug, it
certainly sounded like it was a manifestation of “undefined behavior” as
“Project: Lumbergh” was actinging differently between Linux and Mac OS-X (our
testing and development platforms). The issue stemmed from this bit of code
(not the exact code, but similar in nature):

-----[ C ]-----
x = strtol(input,&endptr,10);
if ((errno == 0) && (endptr != input))
/* ... */
-----[ END OF LINE ]-----

And the fix:

-----[ C ]-----
errno = 0; /* BUG FIX */
x = strtol(input,&endptr,10);
if ((errno == 0) && (endptr != input))
/* ... */
-----[ END OF LINE ]-----

In fact, there are man pages [2] that show setting errno to 0 in sample code.
Here's what the C99 Standard says about library functions setting errno:

> 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.
>
> “C99 Standard, section 7.5.3”
>

So no function will ever set errno to 0. To me, this sounds like some earlier
failed function causing a false problem in this bit of code, thus the fix to
set errno to 0. Now, the C99 Standard says this about strtol():

> The strtol, strtoll, strtoul, and strtoull functions return the converted
> value, if any. If no conversion could be performed, zero is returned. If
> the correct value is outside the range of representable values, LONG_MIN,
> LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX is returned
> (according to the return type and sign of the value, if any), and the value
> of the macro ERANGE is stored in errno.
>
> “C99 Standard, section 7.20.1.4.8”
>

And indeed, on both Linux and Mac OS-X, for values outside the given range,
ERANGE is returned. The issue happens when no conversion happens. Both
systems return 0, but Linux doesn't set errno whereas Mac OS-X does. In fact,
Mac OS-X sets errno to EINVAL, which isn't even defined in the C99 Standard
(but it is defined for POSIX (Portale Operating System Interface)). I think
Mac OS-X has the wrong behavior here. errno is documented in the description
of strtol() (but only for one error case), so Mac OS-X shouldn't be (in my
opinion) errno when there's a conversion issue.

It may be a moot point though, as the fix appears to be working as intended
on both systems.

[1] gopher://gopher.conman.org/0Phlog:2018/09/11.2
[2] https://linux.die.net/man/3/strtol

Email author at [email protected]