2017-06-06 77 views
11

我正在使用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,但在这种情况下不知道正确的格式说明符。

+5

'zu'是C99的补充,也是正确的方法。确保你编译为C99(或更新)。 – StoryTeller

+3

@StoryTeller OP用'-std = c11'编译。 – Stargateur

+0

@StoryTeller我仍然得到一个错误,告诉我它不喜欢“z”,即使我使用-std = c99 – Scooter

回答

15

问题不在于编译器,而在于C库。 MinGW使用Microsoft的“Visual C运行时”(msvcrt),它只符合,它不支持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的特殊问题,我不想链接额外的代码,但这当然是品味的问题。

+1

Visual Studio 2013及更高版本支持“%zu”。用'_MSC_VER> = 1800'检查它。而你声称MSVC不支持'll'就是*完全* false;该支持已经存在*许多*版本,所以很多我不记得什么时候它不被支持。 –

+1

@CodyGray我刚刚检查:'%zu'不支持在我的Windows 10系统上找到的msvcrt.dll版本7.0.10586.0。所以我猜MSVC做了类似MinGW的'__USE_MINGW_ANSI_STDIO',并且链接了一些额外的代码来支持这个? –

+1

嗯,不同的是,MSVC在20年内还没有链接到msvcrt.dll。最后一个使用的版本是VC++ 6.我记得知道这一点,但我不知何故忘记了MinGW正在链接到微软的私有运行时库。我想这是使用DDK链接。对msvcrt.dll的更新没有记录,因为该DLL不适合公开使用。我猜它的'printf'支持没有被扩展,因为微软没有使用它。那么,这不是因为有人需要*更多*不使用MinGW的原因! –

相关问题