I'm parsing a long long value using fgets
and strtoll
as one does, but strtoll
is not setting errno
to ERANGE
when an overflow occurs like it's supposed to.
The
strtol()
function returns the result of the conversion, unless the value would underflow or overflow. If an underflow occurs,strtol()
returnsLONG_MIN
. If an overflow occurs,strtol()
returns LONG_MAX. In both cases,errno
is set toERANGE
. Precisely the same holds forstrtoll()
(with LLONG_MIN and LLONG_MAX instead of LONG_MIN and LONG_MAX).
Sample code without fgets
for MRE purposes:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
int main(){
long long number; //max value 9223372036854775807
char input[] = "12345678976543245678976543";
char *end;
number = strtoll(input, &end, 10);
printf("%d %d <%s> %lld %lld\n", errno, ERANGE, input, (long long)number, LLONG_MAX);
//prints 0 for errno and 34 for ERANGE regardless of overflow
//eerno should be set to ERANGE so it should be 34
int e = errno; //further testing, assigning errno
printf("%d", e);// again prints 0 should be 34
}
Output is:
0 34 <12345678976543245678976543> 9223372036854775807 9223372036854775807
0
Should be:
34 34 <12345678976543245678976543> 9223372036854775807 9223372036854775807
34
This is highly confusing to me, especially because in an online compiler it seems to work fine.
I'm using gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu2), ldd (Ubuntu GLIBC 2.31-0ubuntu9) 2.31 in a recently updated Linux Mint 20.