转换到Windows后,C程序显示%zu

时间:2014-09-04 16:24:31

标签: linux windows g++ cygwin mingw

我通过Mingw在Windows上编写了一个linux程序。但是,程序的输出在Windows上看起来与在Linux上不同。

例如,在Windows上输出是这样的(我得到'zu'而不是实数):

Approximated minimal memory consumption:
Sequence        : zuM
Buffer          : 1 X zuM = zuM
Table           : 1 X zuM = zuM
Miscellaneous   : zuM
Total           : zuM

在Linux上,原始程序编译(没有Mingw)并发出警告。在Windows上,在Mingw下,它会编译为零警告。

我应该注意什么?
Mingw是否提供100%的兼容性,或者我必须修改程序才能在Win上运行?

我不知道要朝哪个方向前进。我应该在哪里开始尝试修复程序?
你认为我有更好的机会与Cygwin?


更新:
维基百科提到:“缺乏对C99的支持导致移植问题,特别是涉及printf样式转换说明符的情况”。 这是我碰到头的事吗?

更新:
我的mingw版本是:

MINGWBASEDIR=C:\MinGW
gcc version 4.8.1 (GCC)
gcc version 4.8.1 (GCC)
GNU gdb (GDB) 7.6.1
GNU ld (GNU Binutils) 2.24
GNU windres (GNU Binutils) 2.24
GNU dlltool (GNU Binutils) 2.24
GNU Make 3.82.90
#define __MINGW32_VERSION           3.20
#define __W32API_VERSION 3.17

(我使用此代码获取版本:

@echo off
REM version-of-mingw.bat
REM credit to Peter Ward work in ReactOS Build Environment RosBE.cmd it gave me a starting point that I edited.
::
:: Display the current version of GCC, ld, make and others.
::

REM %CD% works in Windows XP, not sure when it was added to Windows
REM set MINGWBASEDIR=C:\MinGW
set MINGWBASEDIR=%CD%
ECHO MINGWBASEDIR=%MINGWBASEDIR%
SET PATH=%MINGWBASEDIR%\bin;%SystemRoot%\system32
if exist %MINGWBASEDIR%\bin\gcc.exe (gcc -v 2>&1 | find "gcc version")
REM if exist %MINGWBASEDIR%\bin\gcc.exe gcc -print-search-dirs
if exist %MINGWBASEDIR%\bin\c++.exe (c++ -v 2>&1 | find "gcc version")
if exist %MINGWBASEDIR%\bin\gcc-sjlj.exe (gcc-sjlj.exe -v 2>&1 | find "gcc version")
if exist %MINGWBASEDIR%\bin\gcc-dw2.exe (gcc-dw2.exe -v 2>&1 | find "gcc version")
if exist %MINGWBASEDIR%\bin\gdb.exe (gdb.exe -v | find "GNU gdb")
if exist %MINGWBASEDIR%\bin\nasm.exe (nasm -v)
if exist %MINGWBASEDIR%\bin\ld.exe (ld -v)
if exist %MINGWBASEDIR%\bin\windres.exe (windres --version | find "GNU windres")
if exist %MINGWBASEDIR%\bin\dlltool.exe (dlltool --version | find "GNU dlltool")
if exist %MINGWBASEDIR%\bin\pexports.exe (pexports | find "PExports" )
if exist %MINGWBASEDIR%\bin\mingw32-make.exe (mingw32-make -v | find "GNU Make")
if exist %MINGWBASEDIR%\bin\make.exe (ECHO It is not recommended to have make.exe in mingw/bin)
REM ECHO "The minGW runtime version is the same as __MINGW32_VERSION"
if exist "%MINGWBASEDIR%\include\_mingw.h" (type "%MINGWBASEDIR%\include\_mingw.h" | find "__MINGW32_VERSION" | find "#define")
if exist "%MINGWBASEDIR%\include\w32api.h" (type "%MINGWBASEDIR%\include\w32api.h" | find "__W32API_VERSION")

:_end
PAUSE

1 个答案:

答案 0 :(得分:5)

正如bug report discussion linked in the comments所建议的那样,Microsoft的printf函数不支持C99。 mingw-w64项目提供了替代函数,如果在包含任何头文件或命令行之前将宏__USE_MINGW_ANSI_STDIO设置为1,则可以将它们用作正常的C99函数。它们支持标准%zu%jd等格式说明符,即使是最新的MSVCRT版本也不支持。您可以使用mingw_printf直接调用该函数,但通常更容易将上述宏定义为1并调用printf等。

值得注意的是,如果您使用Microsoft的snprintf,如果缓冲区不够大,它将返回-1表示截断,除非缓冲区和缓冲区大小参数分别为NULL和0 ,在这种情况下,将返回将输出的字节数。 C99行为总是返回缓冲区足够大时将输出的字节数,如果发生编码错误则返回负值,并且mingw-w64实现似乎根据C99正确运行。

如果您使用任何#define __USE_MINGW_ANSI_STDIO 1函数或只是将printf添加到编译器调用中,那么在任何包含之前,您需要做的就是获得所有这些标准行为-D__USE_MINGW_ANSI_STDIO=1

如果您担心宏干扰其他平台,除了提供类似功能的原始(遗留?)MinGW [32]项目之外,其他任何实现都不应该实际使用此预处理器宏,因此可以安全地定义它无条件。