https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72858
--- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> --- I came across one subtle case that I think might be better handled differently than the others. The type of the expected argument to a %lc directive is wint_t, which is commonly int, but on some targets long int. When the promoted type of the argument is int, the hint suggests to replace the %lc directive with %c (even when int and long are the same size). The trouble with the suggestion is that %lc behaves differently than %c in two ways: 1) it first converts the wint_t argument to wchar_t and then to a multibyte character sequence as if by wctomb(), and 2) it produces between zero and MB_CUR_MAX bytes while %c exactly one. This is rather subtle and might be missed by people maintaining internationalization code they're not familiar with, leading them to introduce bugs. To minimize the risk, I think it might be better to change the hint to suggest to cast the %lc argument to wint_t instead on the assumption that the %lc is likely to be correct. Another option might be to suppress the %lc -Wformat warning altogether when the argument's type is an integer with the same precision as wint_t. $ cat /build/tmp/t.c && /build/sysroot/sparc-sun-solaris2.12/bin/sparc-sun-solaris2.12-gcc -S -Wall -m32 /build/tmp/t.c void f (int x) { __builtin_printf ("%lc", x); } /build/tmp/t.c: In function 'f': /build/tmp/t.c:3:24: warning: format '%lc' expects argument of type 'wint_t', but argument 2 has type 'int' [-Wformat=] __builtin_printf ("%lc", x); ~~^ %c