https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88270
--- Comment #3 from Eric Blake <eblake at redhat dot com> --- Confirmed that -Wpendantic flags %m: $ gcc -Wpedantic -Wformat foo.c -o foo foo.c: In function ‘main’: foo.c:3:10: warning: ISO C does not support the ‘%m’ gnu_printf format [-Wformat=] printf("%m %B\n"); ^ foo.c:3:13: warning: unknown conversion type character ‘B’ in format [-Wformat=] printf("%m %B\n"); ^ Although -Wpedantic is a rather heavy hammer compared to a fine-grained knob that can warn for just uses of %m (seeing as how we already have other knobs like -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral -Wformat-overflow=N -Wformat-security -Wformat-signedness -Wformat-truncation=N). Then, as you say, if 'printf' starts flagging %m on BSD, we'd still need some way to specifically mark attributes on wrapper functions that accept more than the system print but less than the full gnu_printf. Maybe we could have multiple fine-grained attributes that each control one class of printf format extensions, which can then be combined as a set, where the existing printf, ms_printf, and gnu_printf are shorthands for specific members in that set? Then specific wrappers can hand-build the set matching what they actually support, rather than relying on the shorthands. Something like: Mark my own function as C89 + %m (but not C99 %hhd) __attribute__ (( format( (printf_c89, printf_m), 1, 0 ) )) Mark another function as supporting %1$'d which is POSIX extensions beyond C99 C: __attribute__ (( format( (printf_c89, printf_c99, printf_posix), 1, 0 ) )) Use the system printf: __attribute__ (( format( printf, 1, 0 ) )) which on glibc would probably be shorthand for: __attribute__ (( format( (printf_c89, printf_c99, printf_posix, printf_m, printf_llg, printf_q, printf_Z), 1, 0 ) )) and on Windows would probably be shorthand for: __attribute__ (( format( (printf_c89, printf_I64), 1, 0 ) )) I don't know what syntax would be best to specify an attribute as a set of fine-grained format pieces that act together as a whole; so much as just tossing out the idea of having finer-grained attributes which can be applied as a set where the existing high-level attributes are then broken into their fine-grained components.