c - MinGW 海湾合作委员会 : "Unknown conversion type character ' h'"(snprintf)

标签 c gcc mingw printf

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

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("%2hhX\n", 250);
    char c[80];
    snprintf(c, sizeof(c), "%2hhX", 250);
    printf("%s\n", 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 变量打印为十六进制值。)

最佳答案

从历史上看,MinGW 的情况有点奇怪,尤其是在 C99 支持方面。 MinGW 主要依赖与 Windows 一起分发的 msvcrt.dll 运行时,并且该运行时不支持 C99。

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

双方都在改进 - GCC 在与 MS 运行时一起使用时对 -Wformat 具有特定支持,例如:

  • -Wpedantic-ms-format 这样 GCC 就不会提示 "I32""I64"(即使它被记录在案,即使在 4.7.0 中我仍然收到关于它无法识别的投诉 - 也许它是全新的)
  • __attribute__((__format__))ms_printf 选项

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

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

不过,GCC 和 MinGW 似乎在更新的版本中还是有点不同步。和以前一样,GCC 不会警告实际上在 MinGW 上不起作用的说明符,它不会提示会起作用的说明符。

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

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

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

关于c - MinGW 海湾合作委员会 : "Unknown conversion type character ' h'"(snprintf),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10678124/

相关文章:

C可变参数宏

c - 如何修复段错误?

linux - OMP 与 x86_64-w64-mingw32-g++ 交叉编译

c++ - MinGW 编译错误 - '__off64_t' 没有命名类型

c - 3求和算法来求方程

c - 已编译编译器对已编译代码的性能

c - 为什么我 fork 的进程将 systemd 作为它们的父进程?

c++ - 我需要制作一个 opencv 64 exe(错误 The procedure entry point could not be loaded)

c++ - 那里有任何可以便携处理*不*在主线程中的 GUI 库吗?

c++ - 指向字符串和字符的指针捕获 22