如何在mingw-w64 gcc 7.1中无需警告地打印size_t?

时间:2022-09-06 07:38:32

I am using the mingw-w64 (x64) fork of minGW as prepared on nuwen.net. This is from the 7.1 version of gcc :

我在nuwen.net上使用minGW的mingw-w64(x64)分支。这是来自7.1版本的gcc:

gcc --version
gcc (GCC) 7.1.0

I am compiling this program:

我正在编译这个程序:

#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);
}

with warnings and c11 standard:

有警告和c11标准:

gcc -Wall -Wextra -Wpedantic -std=c11 test_size_t.c

and I get these warnings:

我收到这些警告:

   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=]

I would like to printf a size_t without warning but don't know the correct format specifier in this situation.

我想在没有警告的情况下printf一个size_t,但在这种情况下不知道正确的格式说明符。

1 个解决方案

#1


16  

The problem is not the compiler but the C library. MinGW uses Microsoft's "Visual C Runtime" (msvcrt) which only conforms to and it doesn't support the z format specifier.

问题不是编译器而是C库。 MinGW使用Microsoft的“Visual C Runtime”(msvcrt),它只符合c89,不支持z格式说明符。

Here's what you can do to safely print a size_t when using MinGW:

以下是使用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);
}

On win64, you would get a warning with this code, because PRIu64 expands to the msvcrt-specific I64u format specifier. But you can silence this warning with the GCC flag -Wno-pedantic-ms-format.

在win64上,您将收到此代码的警告,因为PRIu64扩展为msvcrt特定的I64u格式说明符。但是你可以用GCC标志-Wno-pedantic-ms-format来使这个警告静音。


Note that you need a similar trick for long long (here using PRIu64 on both 32bit and 64bit windows) because msvcrt doesn't know ll either.

请注意,你需要一个长期类似的技巧(这里使用32位和64位窗口上的PRIu64)因为msvcrt也不知道ll。


edit: as pointed out by @M.M in a comment, you can instead link MinGW-provided alternative stdio functions that support C11 with #define __USE_MINGW_ANSI_STDIO 1. I prefer not to link extra code if I can get around the peculiarities of msvcrt, but that's of course a matter of taste.

编辑:正如@MM在评论中指出的那样,您可以将MinGW提供的支持C11的替代stdio函数与#define __USE_MINGW_ANSI_STDIO链接起来1.如果我可以绕过msvcrt的特性,我宁愿不链接额外的代码,但那是当然是品味问题。

#1


16  

The problem is not the compiler but the C library. MinGW uses Microsoft's "Visual C Runtime" (msvcrt) which only conforms to and it doesn't support the z format specifier.

问题不是编译器而是C库。 MinGW使用Microsoft的“Visual C Runtime”(msvcrt),它只符合c89,不支持z格式说明符。

Here's what you can do to safely print a size_t when using MinGW:

以下是使用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);
}

On win64, you would get a warning with this code, because PRIu64 expands to the msvcrt-specific I64u format specifier. But you can silence this warning with the GCC flag -Wno-pedantic-ms-format.

在win64上,您将收到此代码的警告,因为PRIu64扩展为msvcrt特定的I64u格式说明符。但是你可以用GCC标志-Wno-pedantic-ms-format来使这个警告静音。


Note that you need a similar trick for long long (here using PRIu64 on both 32bit and 64bit windows) because msvcrt doesn't know ll either.

请注意,你需要一个长期类似的技巧(这里使用32位和64位窗口上的PRIu64)因为msvcrt也不知道ll。


edit: as pointed out by @M.M in a comment, you can instead link MinGW-provided alternative stdio functions that support C11 with #define __USE_MINGW_ANSI_STDIO 1. I prefer not to link extra code if I can get around the peculiarities of msvcrt, but that's of course a matter of taste.

编辑:正如@MM在评论中指出的那样,您可以将MinGW提供的支持C11的替代stdio函数与#define __USE_MINGW_ANSI_STDIO链接起来1.如果我可以绕过msvcrt的特性,我宁愿不链接额外的代码,但那是当然是品味问题。