如何在mingw-w64 gcc 7.1没有警告的情况下打印size_t?
我正在使用nuwen.net上准备的minGW的mingw-w64(x64)分支。这是从7.1版本的GCC:如何在mingw-w64 gcc 7.1没有警告的情况下打印size_t?
gcc --version
gcc (GCC) 7.1.0
我编译此程序:
#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);
}
警告和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=%lu\n",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=%lu\n",a);
~~^
%I64u
test_size_t.c:7:14: warning: unknown conversion type character 'l' in format [-Wformat=]
printf("a=%llu\n",a);
^
test_size_t.c:7:9: warning: too many arguments for format [-Wformat-extra-args]
printf("a=%llu\n",a);
^~~~~~~~~~
test_size_t.c:7:14: warning: unknown conversion type character 'l' in format [-Wformat=]
printf("a=%llu\n",a);
^
test_size_t.c:7:9: warning: too many arguments for format [-Wformat-extra-args]
printf("a=%llu\n",a);
^~~~~~~~~~
test_size_t.c:8:13: warning: unknown conversion type character 'z' in format [-Wformat=]
printf("a=%zu\n",a);
^
test_size_t.c:8:9: warning: too many arguments for format [-Wformat-extra-args]
printf("a=%zu\n",a);
^~~~~~~~~
test_size_t.c:8:13: warning: unknown conversion type character 'z' in format [-Wformat=]
printf("a=%zu\n",a);
^
test_size_t.c:8:9: warning: too many arguments for format [-Wformat-extra-args]
printf("a=%zu\n",a);
^~~~~~~~~
test_size_t.c:9:9: warning: ISO C does not support the 'I64' ms_printf length modifier [-Wformat=]
printf("a=%I64u\n",a);
^~~~~~~~~~~
test_size_t.c:9:9: warning: ISO C does not support the 'I64' ms_printf length modifier [-Wformat=]
我想t o在没有警告的情况下printf size_t,但在这种情况下不知道正确的格式说明符。
问题不在于编译器,而在于C库。 MinGW使用Microsoft的“Visual C运行时”(msvcrt
),它只符合c89,它不支持z
格式说明符。
这里是你可以做的,使用MinGW的安全时,打印size_t
什么:
#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
特异性I64u
格式说明。但是你可以用GCC标志-Wno-pedantic-ms-format
来消除这个警告。
请注意,你需要一个类似的把戏long long
(这里使用PRIu64
上32位和64位Windows),因为msvcrt
不知道ll
无论是。
编辑:在评论中指出@ M.M,可以改为链接支持C11与#define __USE_MINGW_ANSI_STDIO 1
的MinGW提供的替代stdio
功能。如果我可以解决msvcrt
的特殊问题,我不想链接额外的代码,但这当然是品味的问题。
Visual Studio 2013及更高版本支持“%zu”。用'_MSC_VER> = 1800'检查它。而你声称MSVC不支持'll'就是*完全* false;该支持已经存在*许多*版本,所以很多我不记得什么时候它不被支持。 –
@CodyGray我刚刚检查:'%zu'不支持在我的Windows 10系统上找到的msvcrt.dll版本7.0.10586.0。所以我猜MSVC做了类似MinGW的'__USE_MINGW_ANSI_STDIO',并且链接了一些额外的代码来支持这个? –
嗯,不同的是,MSVC在20年内还没有链接到msvcrt.dll。最后一个使用的版本是VC++ 6.我记得知道这一点,但我不知何故忘记了MinGW正在链接到微软的私有运行时库。我想这是使用DDK链接。对msvcrt.dll的更新没有记录,因为该DLL不适合公开使用。我猜它的'printf'支持没有被扩展,因为微软没有使用它。那么,这不是因为有人需要*更多*不使用MinGW的原因! –
'zu'是C99的补充,也是正确的方法。确保你编译为C99(或更新)。 – StoryTeller
@StoryTeller OP用'-std = c11'编译。 – Stargateur
@StoryTeller我仍然得到一个错误,告诉我它不喜欢“z”,即使我使用-std = c99 – Scooter