一尘不染

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

linux

我通过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


阅读 283

收藏
2020-06-03

共1个答案

一尘不染

正如注释中错误报告讨论所建议的那样,Microsoft的printf功能不支持C99。mingw-w64项目提供了替代功能,如果__USE_MINGW_ANSI_STDIO在包含任何标头之前或在命令行上将宏设置为1
,则它们可以像正常的C99功能一样使用。它们支持标准%zu%jd等格式说明符,即使最新的MSVCRT版本也不支持。您可以直接使用调用该函数mingw_printf,但通常只需将上述宏定义为1并调用printf,这样会更容易。

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

为了使用所有这些标准行为,您需要做的只是#define __USE_MINGW_ANSI_STDIO 1在使用任何printf函数之前都包含在其中,或者只是添加-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.

2020-06-03