https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78304
Bug ID: 78304 Summary: -Wformat doesn't warn anymore for inttypes.h format string argument type mismatches Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: mark at gcc dot gnu.org Target Milestone: --- For this program: #include <inttypes.h> #include <stdio.h> int main (int argc, char **argv) { size_t size = argc; printf ("size: %" PRIu32 "\n", size); return 0; } gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11) warns when given -Wformat: t.c: In function ‘main’: t.c:8:3: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t’ [-Wformat=] printf ("size: %" PRIu32 "\n", size); ^ gcc (GCC) 7.0.0 20161110 (experimental) doesn't give any warning with -Wformat. Note that both versions do warn when using "size: %u\n" as format string: t.c: In function ‘main’: t.c:8:19: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t {aka long unsigned int}’ [-Wformat=] printf ("size: %u\n", size); ~^ %lu They also both warn when using normal string concatenation: t.c: In function ‘main’: t.c:8:11: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t {aka long unsigned int}’ [-Wformat=] printf ("size: %" "u" "\n", size); ^~~~~~~~~ t.c:8:22: note: format string is defined here printf ("size: %" "u" "\n", size); ~~~~^ %" "lu They even both warn when doing the format string define in the file itself: #include <stdio.h> #define UFORMAT "u" int main (int argc, char **argv) { size_t size = argc; printf ("size: %" UFORMAT "\n", size); return 0; } But gcc 4.8.5 has a better warning message: t.c: In function ‘main’: t.c:9:3: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t’ [-Wformat=] printf ("size: %" UFORMAT "\n", size); ^ While 7.0.0 gives the somewhat cryptic: t.c: In function ‘main’: t.c:3:18: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t {aka long unsigned int}’ [-Wformat=] #define UFORMAT "u" ^