Unless I'm missing it, the scanf man page doesn't really specifically address the result of an out-of-range integer conversion -- e.g. sscanf("9999999999999999999999999999999", "%d", &i). The ERRORS section, however, says this: ERANGE The result of an integer conversion would exceed the size that can be stored in the corresponding integer type. This is definitely *not* the behavior that I'm seeing. Instead, sscanf is returning 1 and -1 is assigned to i.
Am 16.09.2013 22:04, schrieb bugzilla-daemon@bugzilla.kernel.org: > sscanf("9999999999999999999999999999999", "%d", &i). please try this code: #include <stdio.h> #include <errno.h> int main() { int ret,i; ret=sscanf("9999999999999999999999999999999", "%d", &i); perror("scanf"); printf("ret=%d i=%d\n",ret,i); return 0; } re, wh
(In reply to walter from comment #1) > please try this code: > > #include <stdio.h> > #include <errno.h> > int main() > { > int ret,i; > ret=sscanf("9999999999999999999999999999999", "%d", &i); > perror("scanf"); > printf("ret=%d i=%d\n",ret,i); > return 0; > } scanf: Numerical result out of range ret=1 i=-1 So it is setting errno, but it's still returning 1. That's just weird. (But allowed, since the behavior is undefined in this case.) Perhaps the ERANGE section could note that it can occur even when the function does not return EOF.
strtod(3) has the following note: NOTES Since 0 can legitimately be returned on both success and failure, the calling program should set errno to 0 before the call, and then determine if an error occurred by checking whether errno has a nonzero value after the call. Maybe add the same note to scanf(3) ? Also, the example program from scanf(3) is: char *p; int n; errno = 0; n = scanf("%m[a-z]", &p); if (n == 1) { printf("read: %s\n", p); free(p); } else if (errno != 0) { perror("scanf"); } else { fprintf(stderr, "No matching characters\n"); } which suggests checking for the return value of scanf before checking for errno, which is wrong in the integer overflow case as scanf returns 1. Change the order of the checks ? Also, for scanf, it doesn't set i to a constant value (adapting the example program to read an int): jon@zog:~$ cat dez.c #include "stdlib.h" #include "stdio.h" #include "errno.h" int main() { int res; int n; errno = 0; n = scanf("%d", &res); if (n == 1) { printf("read: %d\n", res); } else if (errno != 0) { perror("scanf"); } else { fprintf(stderr, "No matching characters\n"); } } jon@zog:~$ for ((i=0; i<30; i++)); do echo "$((10**i -1))" | ./dez; done read: 0 read: 9 read: 99 read: 999 read: 9999 read: 99999 read: 999999 read: 9999999 read: 99999999 read: 999999999 read: 1410065407 read: 1215752191 read: -727379969 read: 1316134911 read: 276447231 read: -1530494977 read: 1874919423 read: 1569325055 read: -1486618625 read: -1981284353 read: 1661992959 read: -559939585 read: -1304428545 read: -159383553 read: -1593835521 read: 1241513983 read: -469762049 read: -402653185 read: 268435455 read: -1610612737