#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) #define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) void _bfd_error_handler (const char *fmt, ...) ATTRIBUTE_PRINTF_1; void foo(void) { _bfd_error_handler("%zu\n", sizeof(0)); } $ gcc -Wall -c bug.c -std=c99 bug.c: In function 'foo': bug.c:6:39: warning: unknown conversion type character 'z' in format [-Wformat=] 6 | void foo(void) { _bfd_error_handler("%zu\n", sizeof(0)); } | ^ bug.c:6:37: warning: too many arguments for format [-Wformat-extra-args] 6 | void foo(void) { _bfd_error_handler("%zu\n", sizeof(0)); } | ^~~~~~~ From my understanding the warning should not happen when `__USE_MINGW_ANSI_STDIO=1`, the difficulty is that it's set in `_mingw.h`, not in GCC itself, and could be set by a user or by other headers. Possible solutions: 1) Lookup real `printf` declaration, but it won't be there if the code doesn't include `stdio.h`. False positives. 2) Query `__USE_MINGW_ANSI_STDIO` and fall back to the used C mode. Code that sets `__USE_MINGW_ANSI_STDIO` different from default value could get false positives on C89 and false negatives on C99, the logic for default value of `__USE_MINGW_ANSI_STDIO` in `_mingw.h` is more complicated than just current C mode. 3) Make GCC always be fine with C99 specifiers for now. Any of the solutions above would be better than `-Wno-format`.
So there is mingw_printf and gnu_printf attributes for mingw because at one point %ll didn't exist for mingw and nobody has updated it since then.
(In reply to Andrew Pinski from comment #1) > So there is mingw_printf and gnu_printf attributes for mingw because at one > point %ll didn't exist for mingw and nobody has updated it since then. Sorry I mean ms_printf rather than mingw_printf. Anyways this is all documented: https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Common-Function-Attributes.html#index-format-function-attribute
If anything gnu_printf should be used instead for _bfd_error_handler and that would be a binutils issue and reported there ...
This is documented this way. If you want to use C99 printf format, you need to use gnu_printf instead (note gnu_printf format is for all targets and not just mingw).
> So there is mingw_printf and gnu_printf attributes for mingw because at one point %ll didn't exist for mingw and nobody has updated it since then. Do you mean that binutils and [other code out there](https://github.com/search?q=%2F__attribute__%5Cs*%5C%28%5Cs*%5C%28%5Cs*_*format_*%5Cs*%5C%28%5Cs*_*printf%2F&type=code) should be updated to use gnu_printf in attributes? That would be a lot of work, clang doesn't know gnu_printf, and is wrong for actual printf wrappers.
(In reply to Nikita Kniazev from comment #5) > > So there is mingw_printf and gnu_printf attributes for mingw because at one point %ll didn't exist for mingw and nobody has updated it since then. > > Do you mean that binutils and [other code out > there](https://github.com/ > search?q=%2F__attribute__%5Cs*%5C%28%5Cs*%5C%28%5Cs*_*format_*%5Cs*%5C%28%5Cs > *_*printf%2F&type=code) should be updated to use gnu_printf in attributes? > That would be a lot of work, clang doesn't know gnu_printf, and is wrong for > actual printf wrappers. This has been documented/implemented this way for ~16 years now (for GCC 4.4.0), r0-86297-g6590fc9fbd071d . https://inbox.sourceware.org/gcc-patches/OF604F1098.0E3FE32A-ONC1257408.003BB78C-C1257408.003CE7F2@onevision.de/
(In reply to Andrew Pinski from comment #6) > (In reply to Nikita Kniazev from comment #5) > > > So there is mingw_printf and gnu_printf attributes for mingw because at one point %ll didn't exist for mingw and nobody has updated it since then. > > > > Do you mean that binutils and [other code out > > there](https://github.com/ > > search?q=%2F__attribute__%5Cs*%5C%28%5Cs*%5C%28%5Cs*_*format_*%5Cs*%5C%28%5Cs > > *_*printf%2F&type=code) should be updated to use gnu_printf in attributes? > > That would be a lot of work, clang doesn't know gnu_printf, and is wrong for > > actual printf wrappers. > > This has been documented/implemented this way for ~16 years now (for GCC > 4.4.0), r0-86297-g6590fc9fbd071d . > > https://inbox.sourceware.org/gcc-patches/OF604F1098.0E3FE32A-ONC1257408. > 003BB78C-C1257408.003CE7F2@onevision.de/ Which attributes should use for void my_printf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); printf(fmt, ap); va_end(ap); } so it will behave correctly with any combination of -std=c89, -std=c99, __USE_MINGW_ANSI_STDIO=0, __USE_MINGW_ANSI_STDIO=1, _UCRT
(In reply to Nikita Kniazev from comment #7) > (In reply to Andrew Pinski from comment #6) > > (In reply to Nikita Kniazev from comment #5) > > > > So there is mingw_printf and gnu_printf attributes for mingw because at one point %ll didn't exist for mingw and nobody has updated it since then. > > > > > > Do you mean that binutils and [other code out > > > there](https://github.com/ > > > search?q=%2F__attribute__%5Cs*%5C%28%5Cs*%5C%28%5Cs*_*format_*%5Cs*%5C%28%5Cs > > > *_*printf%2F&type=code) should be updated to use gnu_printf in attributes? > > > That would be a lot of work, clang doesn't know gnu_printf, and is wrong for > > > actual printf wrappers. > > > > This has been documented/implemented this way for ~16 years now (for GCC > > 4.4.0), r0-86297-g6590fc9fbd071d . > > > > https://inbox.sourceware.org/gcc-patches/OF604F1098.0E3FE32A-ONC1257408. > > 003BB78C-C1257408.003CE7F2@onevision.de/ > > Which attributes should use for > > void my_printf(const char *fmt, ...) > { > va_list ap; > > va_start(ap, fmt); > printf(fmt, ap); > va_end(ap); > } > > so it will behave correctly with any combination of -std=c89, -std=c99, > __USE_MINGW_ANSI_STDIO=0, __USE_MINGW_ANSI_STDIO=1, _UCRT that is a good question but that is a question for the mingw forums really rather than inside gcc bugzilla.
Ok, is there at least an option to build GCC so it defaults __printf__ to gnu_printf? Defaulting __printf__ to ms_printf on UCRT is wrong (every OS without UCRT is already EOL).
(In reply to Nikita Kniazev from comment #9) > Ok, is there at least an option to build GCC so it defaults __printf__ to > gnu_printf? Defaulting __printf__ to ms_printf on UCRT is wrong (every OS > without UCRT is already EOL). There is none yet. But any fix won't happen until GCC 15 really ...
-mcrtdll=ucrt should make __printf__ be gnu_printf instead of ms_printf. Should I file separate issue or this one can be reopened?
(In reply to Nikita Kniazev from comment #11) > -mcrtdll=ucrt should make __printf__ be gnu_printf instead of ms_printf. > Should I file separate issue or this one can be reopened? The reality is ms_printf most likely should just include z and ll support instead since they are supported now: https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-170 They have been included since 2015. As I mentioned GCC mingw support is out of date really and should be fixed there .
(In reply to Andrew Pinski from comment #12) > The reality is ms_printf most likely should just include z and ll support > instead since they are supported now: > https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification- > syntax-printf-and-wprintf-functions?view=msvc-170 While it makes sense, if ms_printf and gnu_printf will behave the same - there is no point in having them then. (In reply to Andrew Pinski from comment #12) > As I mentioned GCC mingw support is out of date really and should be fixed there . Fixed where? IIUC the machinery is in gcc/config/i386/msformat-c.cc
*** Bug 116232 has been marked as a duplicate of this bug. ***
https://github.com/brechtsanders/winlibs_mingw/issues/233