https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60296
Manuel López-Ibáñez <manu at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED CC| |manu at gcc dot gnu.org Resolution|--- |INVALID --- Comment #2 from Manuel López-Ibáñez <manu at gcc dot gnu.org> --- To be honest, I find the messages by gcc far clearer (except for missing precise locations). In particular, if we think about suggesting a fix, gcc could suggest to replace %. with %.d to match '9' and then the second warning will still be valid (since there are no arguments to match %*d). Currently, gcc tries to match 9 to %. and skips both on error, that is why it complains about a missing argument for %d. GCC could not skip the argument '9' and try to match %*d with 9. I can imagine cases where one strategy is clearer than the other and viceversa. However, the clang warning does not actually say what is wrong at all. It does not seem very helpful. About your questions, yes %d refers to %*d in the format string, and the %d printed by the warning is not read from the string but hard-coded in the gcc sources. What printf does when given invalid arguments is not up to GCC but the C library that implements printf. I will close this as invalid then. Improving the location info is what will make these cases far clearer (PR52952). Then, we can print: warning: conversion lacks type at end of format [-Wformat=] printf("%.%*d\n", 9); ~^ note: use '%.d' to match argument of type 'int' printf("%.%*d\n", 9); ~^ ^ %.d warning: format ‘%d’ expects a matching ‘int’ argument [-Wformat=] printf("%.%*d\n", 9); ^