从历史上看,MinGW 的处境有点奇怪,尤其是就 C99 支持而言。 MinGW 主要依赖于随 Windows 一起分发的 msvcrt.dll 运行时,并且该运行时不支持 C99。
因此,对于旧版本的 MinGW,当使用 C99 特定的格式说明符时,您可能会在 C99 模式下遇到问题。同样从历史上看,GCC 并没有针对 msvcrt.dll 缺乏对 C99 说明符的支持做出任何特殊调整。所以你会遇到这样的情况-Wformat
不会警告无法使用的格式。
双方的情况都在改善 - 当与 MS 运行时一起使用时,GCC 对 -Wformat 提供了特定支持,例如:
-
-Wpedantic-ms-format
这样海湾合作委员会就不会抱怨"I32"
and "I64"
(尽管它已被记录,但我仍然收到关于它无法识别的抱怨,即使在 4.7.0 中 - 也许它是全新的)
- the
ms_printf
选项__attribute__((__format__))
另一方面,MinGW 提供了自己的snprintf()
有一段时间,自从MSVC的变种以来,_snprintf()
,行为完全不同。然而,MinGW 长期以来依赖于printf()
在 msvcrt.dll 中,因此 C99 格式说明符为printf()
没用。在某个时候,MinGW 开始提供它自己的版本printf()
和朋友,以便您可以获得适当的 C99(和 GNU?)支持。然而,从保守的角度来看,这些版本最初并没有取代 msvcrt.dll 版本。他们的名字像__mingw_printf()
.
看起来在 4.6.1 和 4.7.0 之间的某个时刻,MinGW 标头开始使用 MinGW 提供的版本作为 msvcrt.dll 函数的替代品(至少如果您指定了 C99)。
不过,似乎在新版本中,GCC 和 MinGW 还是有点不同步。与以前一样,GCC 不会警告那些实际上无法在 MinGW 上运行的说明符,但它不会抱怨能够在 MinGW 上运行的说明符。
您可能需要尝试以下代码片段来查看您的 MinGW 版本的支持情况"hhX"
:
printf("%hhX\n", 0x11223344);
__mingw_printf("%hhX\n", 0x11223344);
我不确定如何建议来解决您遇到的问题 - 我认为您可以修补 MinGWstdio.h
标头,使其具有__attribute__((__format__ (gnu_printf, ...)))
printf 函数上的属性(它们在较新的版本中不存在)stdio.h
,因此 GCC 将使用其默认的格式支持概念)。