> conventional, consistent[1], and documented--semantics of only setting errno on error.
From that man page:
> The implementation may also set errno to EINVAL in case no conversion was performed (no digits seen, and 0 returned).
There are error cases where the implementation may set errno to EINVAL. There's not even a guarantee. I did a quick test. errno is only set if you pass an invalid base, or if the string does contain a number but it is out of range. If you pass a string which doesn't even remotely look like a number, errno is not set. You have to check endptr.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
const char *s = "this is not a number";
printf("strtol(\"%s\")\n", s);
errno = 0;
long a = strtol(s, NULL, 10);
printf("errno: %d; strerror: %s\n", errno, strerror(errno));
printf("result: %d\n", a);
return 0;
}
Output: strtol("this is not a number")
errno: 0; strerror: Success
result: 0
https://godbolt.org/z/TbEKss8zMThat's just rubbish design. In what is in my opinion the most common error case, namely that the string doesn't represent a number while you expect that it does, errno is not set.