sscanf(3)
says (emphasis mine):
i
Matches an optionally signed integer; the next pointer must be a pointer toint
. The integer is read in base 16 if it begins with0x
or0X
, in base 8 if it begins with0
, and in base 10 otherwise. Only characters that correspond to the base are used.
However GCC does not complain about using an unsigned int
with %i
unless -pedantic
is given. This is different from the behavior I'm used to, where GCC will warn for any mismatched type and format string.
Why does this combination behave differently?
Given that this warning is not included in the common -Wall
set of warnings, is it acceptable to pass unsigned int
to %i
?
Example program:
#include <stdio.h>
int main(void)
{
int i;
unsigned int u;
float f;
scanf("%i", &i);
scanf("%i", &u);
scanf("%i", &f);
return 0;
}
Without -pedantic
, GCC complains about %i
and float *
, but not unsigned int *
:
$ gcc -Wall -Wextra scanf_i.c
scanf_i.c: In function ‘main’:
scanf_i.c:11:13: warning: format ‘%i’ expects argument of type ‘int *’, but argument 2 has type ‘float *’ [-Wformat=]
scanf("%i", &f);
~^ ~~
%e
With -pedantic
, GCC complains about both:
Output with -pedantic
:
$ gcc -Wall -Wextra -pedantic scanf_i.c
scanf_i.c: In function ‘main’:
scanf_i.c:10:13: warning: format ‘%i’ expects argument of type ‘int *’, but argument 2 has type ‘unsigned int *’ [-Wformat=]
scanf("%i", &u);
~^ ~~
%i
scanf_i.c:11:13: warning: format ‘%i’ expects argument of type ‘int *’, but argument 2 has type ‘float *’ [-Wformat=]
scanf("%i", &f);
~^ ~~
%e
GCC version:
$ gcc --version
gcc (Debian 8.3.0-6) 8.3.0