It is such a case, it's just not about zero. If the input is too large to be represented in a signed long, strtol(3) returns LONG_MAX and sets errno to ERANGE. However, if the input was the string form of LONG_MAX, it returns LONG_MAX and doesn't set errno to anything. In fact my strtol(3) manpage explicitly states "This function does not modify errno on success".
Thus, to distinguish between an overflow and a legitimate maximum value, you need to set errno to 0 before calling it, because something else you called previously may have already set it to ERANGE.
Thus, to distinguish between an overflow and a legitimate maximum value, you need to set errno to 0 before calling it, because something else you called previously may have already set it to ERANGE.