Soc*_*cob 14 c printf gcc mingw
好吧,我遇到了一个奇怪的问题,在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;
}
Run Code Online (Sandbox Code Playgroud)
编译结果如下:
$ 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]
Run Code Online (Sandbox Code Playgroud)
现在,对我来说很奇怪的是,它抱怨snprintf
第6行的电话,而不是第printf
4行的电话.我错过了什么或警告是不正确的?另外,格式字符串可能有更好的等价物"%2hhX"
吗?(我正在尝试将char变量打印为十六进制值.)
Mic*_*urr 20
从历史上看,MinGW在一些奇怪的情况下,特别是在C99支持下.MinGW主要依赖于随Windows一起发布的msvcrt.dll运行时,并且该运行时不支持C99.
因此,对于旧版本的MinGW,使用C99特定的格式说明符时,可能会在C99模式下遇到问题.同样在历史上,GCC没有为msvcrt.dll缺乏对C99说明符的支持做任何特殊的调整.因此,您将遇到-Wformat
无法警告无法使用的格式的情况.
双方都在改进 - GCC在与MS运行时一起使用时特别支持-Wformat,例如:
-Wpedantic-ms-format
所以海湾合作委员会不会抱怨"I32"
和"I64"
(即使有记录,我仍然抱怨它即使在4.7.0中也未被承认 - 也许它是全新的)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上工作的说明者,而不是它会抱怨那些会产生spcifiers的.
您可能需要尝试以下snipet代码来查看您的MinGW版本支持的程度"hhX"
:
printf("%hhX\n", 0x11223344);
__mingw_printf("%hhX\n", 0x11223344);
Run Code Online (Sandbox Code Playgroud)
我不确定要解决你遇到的问题是什么建议 - 我认为你可以修补MinGW stdio.h
标题,使它__attribute__((__format__ (gnu_printf, ...)))
在printf函数上有一个属性(它们不在新的stdio.h
,所以GCC将使用它的格式支持的默认概念).