我通过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
)
正如注释中的错误报告讨论所建议的那样,Microsoft的printf功能不支持C99。mingw-w64项目提供了替代功能,如果__USE_MINGW_ANSI_STDIO在包含任何标头之前或在命令行上将宏设置为1 ,则它们可以像正常的C99功能一样使用。它们支持标准%zu,%jd等格式说明符,即使最新的MSVCRT版本也不支持。您可以直接使用调用该函数mingw_printf,但通常只需将上述宏定义为1并调用printf,这样会更容易。
printf
__USE_MINGW_ANSI_STDIO
%zu
%jd
mingw_printf
值得注意的是,如果使用Microsoft的snprintf,如果缓冲区不够大,它将返回-1表示截断,除非buffer和buffer size参数分别为NULL和0,在这种情况下,将输出的字节数为回。C99的行为是始终返回如果缓冲区足够大时将输出的字节数,如果出现编码错误则返回负值,并且mingw-w64实现似乎按照C99正确地运行。
snprintf
NULL
为了使用所有这些标准行为,您需要做的只是#define __USE_MINGW_ANSI_STDIO 1在使用任何printf函数之前都包含在其中,或者只是添加-D__USE_MINGW_ANSI_STDIO=1到编译器调用中。
#define __USE_MINGW_ANSI_STDIO 1
-D__USE_MINGW_ANSI_STDIO=1
If you are worried about the macro interfering with other platforms, no other implementation except the original (legacy?) MinGW[32] project that provided similar functionality should actually make use of this preprocessor macro, so it is safe to define it unconditionally.