MinGW GCC:“未知的转换类型字符‘h’";(snprintf) [英] MinGW GCC: "Unknown conversion type character 'h'" (snprintf)

查看:26
本文介绍了MinGW GCC:“未知的转换类型字符‘h’";(snprintf)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我在 Windows 7 上使用 MinGW (GCC 4.6.2) 编译 C 文件时遇到了一个奇怪的问题.有问题的文件包含以下 C 代码:

Okay, I've run into a strange issue compiling a C file with MinGW (GCC 4.6.2) on Windows 7. The file in question contains the following C code:

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("%2hhX
", 250);
    char c[80];
    snprintf(c, sizeof(c), "%2hhX", 250);
    printf("%s
", c);
    return 0;
}

编译结果是这样的:

$ gcc.exe -std=c99 -pedantic -Wall test.c
test.c: In function 'main':
test.c:6:2: warning: unknown conversion type character 'h' in format [-Wformat]
test.c:6:2: warning: too many arguments for format [-Wformat-extra-args]

现在,对我来说奇怪的是它抱怨第 6 行的 snprintf 调用,而不是第 4 行的 printf 调用.我是不是遗漏了什么?警告不正确?另外,格式字符串 "%2hhX" 是否有更好的等价物?(我正在尝试将 char 变量打印为十六进制值.)

Now, what's strange to me is that it complains about the snprintf call on line 6, but not the printf call on line 4. Am I missing something or is the warning just incorrect? Also, is there perhaps a better equivalent for the format string "%2hhX"? (I'm trying to print char variables as hexadecimal values.)

推荐答案

从历史上看,MinGW 一直处于一种奇怪的境地,尤其是就 C99 支持而言.MinGW 主要依赖与 Windows 一起分发的 msvcrt.dll 运行时,并且该运行时不支持 C99.

Historically, MinGW has been in a bit of an odd situation, especially as far as C99 support goes. MinGW relies mostly on the msvcrt.dll runtime that's distributed with Windows, and that runtime doesn't support C99.

因此,对于旧版本的 MinGW,在使用 C99 特定格式说明符时,您可能会在 C99 模式下遇到问题.同样在历史上,GCC 没有为 msvcrt.dll 缺乏对 C99 说明符的支持做出任何特殊调整.因此,您会遇到 -Wformat 不会警告无法使用的格式的情况.

So with older versions of MinGW, you can run into problems in C99 mode when using C99-specific format specifiers. Also historically, GCC didn't make any special accommodations for msvcrt.dll's lack of support for C99 specifiers. So you'd get into situations where -Wformat wouldn't warn about a format that wouldn't work.

双方的情况都在改善 - GCC 在与 MS 运行时一起使用时特别支持 -Wformat,例如:

Things are improving on both sides - GCC has specific support for -Wformat when used with the MS runtime, such as:

  • -Wpedantic-ms-format 以便 GCC 不会抱怨 "I32""I64"(即使它已记录在案,即使在 4.7.0 中,我仍然抱怨它无法识别 - 也许它是全新的)
  • ms_printf 选项到 __attribute__((__format__))
  • -Wpedantic-ms-format so that GCC won't complain about "I32" and "I64" (even though it's documented, I still get a complaint about it being unrecognized even in 4.7.0 - maybe it's brand new)
  • the ms_printf option to __attribute__((__format__))

另一方面,MinGW 已经提供了自己的 snprintf() 一段时间,因为 MSVC 的变体 _snprintf() 的行为完全不同.但是,MinGW 长时间依赖 msvcrt.dll 中的 printf(),因此 printf() 的 C99 格式说明符不起作用.在某些时候,MinGW 开始提供它自己版本的 printf() 和朋友,以便您可以获得适当的 C99(和 GNU?)支持.然而,从保守的角度来看,这些最初并没有取代 msvcrt.dll 版本.它们的名称类似于 __mingw_printf().

On the other side, MinGW has provided its own snprintf() for a while, since MSVC's variant, _snprintf(), behaves quite differently. However, MinGW relied for a long while on the printf() in msvcrt.dll, so C99 format specifiers for printf() didn't work. At some point MinGW started providing it's own version of printf() and friends so that you could get proper C99 (and GNU?) support. However, it seems that to be on the conservative side, these didn't replace the msvcrt.dll versions initially. They have names like __mingw_printf().

看起来在 4.6.1 和 4.7.0 之间的某个时间点,MinGW 标头开始使用 MinGW 提供的版本作为 msvcrt.dll 函数的替代品(至少如果您指定了 C99).

It looks like at some point between 4.6.1 and 4.7.0, the MinGW headers started using the MinGW supplied versions as replacements for the msvcrt.dll function (at least if you've specifed C99).

不过,似乎在更新的版本中,GCC 和 MinGW 仍然有点不同步.与以前一样,GCC 不会警告实际上在 MinGW 上不起作用的说明符,而不是抱怨会起作用的说明符.

However, it seems that with the newer versions, GCC and MinGW are still a little out of sync. Where as before GCC would not warn about specifiers that wouldn't actually work on MinGW, not it complains about spcifiers that will.

您可能想尝试以下代码片段,以查看您的 MinGW 版本对 "hhX" 的支持情况:

You may want to try the following snipet of code to see how well your version of MinGW support "hhX":

printf("%hhX
", 0x11223344);
__mingw_printf("%hhX
", 0x11223344);

我不知道有什么建议可以解决您遇到的问题 - 我认为您可以修补 MinGW stdio.h 标头,使其具有 __attribute__((__format__ (gnu_printf, ...))) 属性在 printf 函数上(它们在较新的 stdio.h 中不存在,因此 GCC 将使用它的默认想法格式支持是什么).

I'm not sure what to suggest to fix the problem you're running into - I think that you may be able to patch the MinGW stdio.h header so that it has a __attribute__((__format__ (gnu_printf, ...))) attribute on the printf functions (they're not there in the newer stdio.h, so GCC will use it's default idea of what the format support is).

这篇关于MinGW GCC:“未知的转换类型字符‘h’";(snprintf)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆