почему компилятор Mingw-w64 g cc выдаст неверное предупреждение о формате% zd и% a - PullRequest
0 голосов
/ 17 января 2020

Я использую компилятор g cc, командная строка -

{gcc 'hellowo.c' -o 'hellowo.exe' -Wall -g -O2 -static-libgcc -std=c11 -fexec-charset=GBK}

, а информация о редактировании -

gcc version 8.1.0 (x86_64-win32-seh-rev0, Built by MinGW-W64 project)

, когда я пытаюсь

#include <stdio.h>

int main(void)
{
    float float1 = 64.25f;
    printf("%zd\n",sizeof(int));
    printf("%a",float1); //float1=64.25f
    return 0;
}

компилятор предупреждает меня:

hellowo.c: In function 'main':
hellowo.c:6:12: warning: unknown conversion type character 'z' in format [-Wformat=]
     printf("%zd\n",sizeof(int));
            ^~~~~~~
hellowo.c:6:12: warning: too many arguments for format [-Wformat-extra-args]
hellowo.c:6:12: warning: unknown conversion type character 'z' in format [-Wformat=]
hellowo.c:6:12: warning: too many arguments for format [-Wformat-extra-args]
hellowo.c:7:12: warning: unknown conversion type character 'a' in format [-Wformat=]
     printf("%a",float1); //float1=64.25f
            ^~~~
hellowo.c:7:12: warning: too many arguments for format [-Wformat-extra-args]
hellowo.c:7:12: warning: unknown conversion type character 'a' in format [-Wformat=]
hellowo.c:7:12: warning: too many arguments for format [-Wformat-extra-args]

однако вывод

4
0x1.010000p+6

почему это произойдет, я использую пример C primer plus учиться самостоятельно

Странно, что .exe может работать хорошо, и моя программа может быть успешно скомпилирована.

Я пытаюсь изменить% zd на% zu, (выражение "% zd" пример C primer plus )

все еще содержит предупреждение:

hellowo.c:6:12: warning: unknown conversion type character 'z' 
in format [-Wformat=]
     printf("%zu\n",sizeof(int));
            ^~~~~~~
hellowo.c:6:12: warning: too many arguments for format [-Wformat-extra-args]
hellowo.c:6:12: warning: unknown conversion type character 'z' 
in format [-Wformat=]
hellowo.c:6:12: warning: too many arguments for format [-Wformat-extra-args]

почему компилятор Mingw-w64 g cc выдаст неверное предупреждение о формате% zd и% a?

1 Ответ

1 голос
/ 17 января 2020

Это неполный ответ.

Функция 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...