#include <stdio.h>
void a(signed char a) {
printf("%u\n", a);
}
void b(short b) {
printf("%u\n", b);
}
void c(int c) {
printf("%u\n", c);
}
void d(long d) {
printf("%u\n", d);
}
void e(long long e) {
printf("%u\n", e);
}
int main() {
a(-1); //no warning
b(-1); //no warning
c(-1); //no warning
d(-1); //warning
e(-1); //warning
return 0;
}
Compiled and tested with gcc 11.2.0 using gcc -std=c17 -pedantic -Wall -Wextra test.c
and g -std=c 17 -pedantic -Wall -Wextra test.cpp
. Both don't give any warning to a()
, b()
, and c()
. Is this intended, or a bug?
CodePudding user response:
Short answer: C warnings are a mystery. Use -Wformat-signedness
if you want warnings here.
Note that -Wformat-signedness
requires -Wformat
, which is already enabled by -Wall
.
Apparently, the compiler only checks for sign mismatches when -Wformat-signedness
is used. -Wall
and -Wextra
don't include -Wformat-signedness
. I don't know why this is. Someone said it's because it would result in too many warnings, but that tells me it really needs to be used if it's such a common error!
So, all that's being checked are size mismatches. The two that warn (d
and e
) warn because a value of a type that's potentially larger than int
is being passed. As for the other two, signed char
and short int
values are promoted to int
values when passed to variadric (...
) functions like printf
, so a
and b
are equivalent to c
.