Как распечатать размер t без предупреждения в mingw-w64 gcc 7.1?
Я использую вилку mingw-w64 (x64) minGW, как подготовлено на nuwen.net - ... Это из версии 7.1 gcc:
gcc --version
gcc (GCC) 7.1.0
я компилирую эту программу:
#include <stdio.h>
int main(void)
{
size_t a = 100;
printf("a=%lun",a);
printf("a=%llun",a);
printf("a=%zun",a);
printf("a=%I64un",a);
}
с предупреждениями и стандартом c11:
gcc -Wall -Wextra -Wpedantic -std=c11 test_size_t.c
и я получаю эти предупреждения:
test_size_t.c: In function 'main':
test_size_t.c:6:14: warning: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'size_t {aka long long unsigned int}' [-Wformat=]
printf("a=%lun",a);
~~^
%I64u
test_size_t.c:6:14: warning: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'size_t {aka long long unsigned int}' [-Wformat=]
printf("a=%lun",a);
~~^
%I64u
test_size_t.c:7:14: warning: unknown conversion type character 'l' in format [-Wformat=]
printf("a=%llun",a);
^
test_size_t.c:7:9: warning: too many arguments for format [-Wformat-extra-args]
printf("a=%llun",a);
^~~~~~~~~~
test_size_t.c:7:14: warning: unknown conversion type character 'l' in format [-Wformat=]
printf("a=%llun",a);
^
test_size_t.c:7:9: warning: too many arguments for format [-Wformat-extra-args]
printf("a=%llun",a);
^~~~~~~~~~
test_size_t.c:8:13: warning: unknown conversion type character 'z' in format [-Wformat=]
printf("a=%zun",a);
^
test_size_t.c:8:9: warning: too many arguments for format [-Wformat-extra-args]
printf("a=%zun",a);
^~~~~~~~~
test_size_t.c:8:13: warning: unknown conversion type character 'z' in format [-Wformat=]
printf("a=%zun",a);
^
test_size_t.c:8:9: warning: too many arguments for format [-Wformat-extra-args]
printf("a=%zun",a);
^~~~~~~~~
test_size_t.c:9:9: warning: ISO C does not support the 'I64' ms_printf length modifier [-Wformat=]
printf("a=%I64un",a);
^~~~~~~~~~~
test_size_t.c:9:9: warning: ISO C does not support the 'I64' ms_printf length modifier [-Wformat=]
Я хотел бы распечатать size_t без предупреждения, но не знаю правильного спецификатора формата в этой ситуации.
2 ответов
проблема не в компиляторе, а в библиотеке C. MinGW использует Microsoft "Visual C Runtime" (msvcrt
), который соответствует только c89 и он не поддерживает z
формат описателя.
вот что вы можете сделать, чтобы безопасно вывести size_t
при использовании MinGW:
#include <inttypes.h>
#include <stdio.h>
#ifdef _WIN32
# ifdef _WIN64
# define PRI_SIZET PRIu64
# else
# define PRI_SIZET PRIu32
# endif
#else
# define PRI_SIZET "zu"
#endif
int main(void)
{
size_t mySize = 24;
printf("%" PRI_SIZET "\n", mySize);
}
на Win64, вы получите предупреждение с этим кодом, потому что PRIu64
увеличивается до msvcrt
- specific I64u
формат описателя. Но ты можешь заглушить это предупреждение Флаг GCC -Wno-pedantic-ms-format
.
обратите внимание, что вам нужен подобный трюк для long long
(здесь с помощью PRIu64
на 32bit и 64bit windows), потому что msvcrt
Не знаю ll
либо.
редактировать: как указал @M. M в комментарии, Вы можете вместо этого связать MinGW-предоставленную альтернативу stdio
функции, которые поддерживают C11 с #define __USE_MINGW_ANSI_STDIO 1
. Я предпочитаю не связывать дополнительный код, если я могу обойти специфика msvcrt
, но это конечно дело вкуса.
альтернативное решение, как указано в комментариях, - это бросить __USE_MINGW_ANSI_STDIO
компилятора:
#define __USE_MINGW_ANSI_STDIO 1
#include <stdio.h>
int main(void)
{
size_t a = 100;
printf("a=%lu\n",a);
printf("a=%llu\n",a);
printf("a=%zu\n",a);
printf("a=%I64u\n",a);
}
Это делает компиляцию кода ожидаемой, и gcc теперь дает соответствующие предупреждения:
warning: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'size_t' [-Wformat=]
warning: ISO C does not support the 'I' printf flag [-Wformat=]
warning: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'size_t' [-Wformat=]