Это неполный ответ.
Функция printf
и поддерживаемые форматы не реализованы вашим компилятором. Они реализованы библиотекой времени выполнения. В случае MinGW компилятор является версией g cc, а библиотека времени выполнения, если я не ошибаюсь, предоставлена Microsoft для Windows.
g cc Компилятор также может предупреждать о строках формата printf
, которые он считает неправильными, например, если вы пытаетесь использовать %s
для вывода аргумента типа int
. Он должен сделать некоторые предположения о том, что поддерживает библиотека времени выполнения. Обычно это просто соответствует правилам C стандарта. Но с -std=c11
я удивлен, что он будет жаловаться на %zd
и %a
, которые действительны C с C99. (Некоторые версии библиотеки времени выполнения Microsoft могут не поддерживать их, но это не должно влиять на поведение во время компиляции.)
Суть в том, что ваш компилятор решил, по какой-то неизвестной причине, что он не ' эти форматы не распознаются, но реализация printf
в библиотеке времени выполнения обрабатывает их правильно. Где-то между вашим компилятором и библиотекой времени выполнения есть несоответствие. g cc, вероятно, использует некоторую heuristi c, чтобы догадаться, что определенные форматы, введенные в C99, не поддерживаются, и в этом случае он угадывает неправильно. Возможно, Microsoft недавно обновила свою библиотеку времени выполнения, и g cc не догнал это изменение.
Предупреждения не должны влиять на поведение вашей программы после ее компиляции и компоновки.
Между прочим, правильный формат для значения size_t
- %zu
, а не %zd
, поскольку size_t
- это тип без знака. %zd
, вероятно, будет работать в этом случае, но все равно используйте %zu
.
Я могу воспроизвести проблему с x86_64-w64-mingw32-gcc.exe
(версия 7.4.0) в Cygwin. Удаление -Wall
блокирует предупреждение.
Вы можете избежать проблемы, передав опцию -D__USE_MINGW_ANSI_STDIO
в g cc. Это заставляет его использовать другую реализацию для printf
.