Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
454 views
in Technique[技术] by (71.8m points)

linux - C program shows %zu after conversion to Windows

I complied a linux program on windows via Mingw. However, the output of the program looks different on Windows than on Linux.

For example, on Windows the output is this (I get 'zu' instead of real numbers):

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

On Linux, the original program compiles (without Mingw) with a warning. On Windows, under Mingw, it compiles with zero warnings.

There is anything I should be aware about?
Does Mingw offer 100% compatibility or I have to modify the program to work on Win?

I don't know in which direction to head. Where should I start my attempt of fixing the program?
Do you think I have better chances with Cygwin?


Update:
Wikipedia mentions this: "the lack of support for C99 has caused porting problems, particularly where printf-style conversion specifiers are concerned".
Is this the thing in which I bumped my head?

Update:
My mingw version is:

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

(I used this code to get the version:

@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%in;%SystemRoot%system32
if exist %MINGWBASEDIR%ingcc.exe (gcc -v 2>&1 | find "gcc version")
REM if exist %MINGWBASEDIR%ingcc.exe gcc -print-search-dirs
if exist %MINGWBASEDIR%inc++.exe (c++ -v 2>&1 | find "gcc version")
if exist %MINGWBASEDIR%ingcc-sjlj.exe (gcc-sjlj.exe -v 2>&1 | find "gcc version")
if exist %MINGWBASEDIR%ingcc-dw2.exe (gcc-dw2.exe -v 2>&1 | find "gcc version")
if exist %MINGWBASEDIR%ingdb.exe (gdb.exe -v | find "GNU gdb")
if exist %MINGWBASEDIR%in
asm.exe (nasm -v)
if exist %MINGWBASEDIR%inld.exe (ld -v)
if exist %MINGWBASEDIR%inwindres.exe (windres --version | find "GNU windres")
if exist %MINGWBASEDIR%indlltool.exe (dlltool --version | find "GNU dlltool")
if exist %MINGWBASEDIR%inpexports.exe (pexports | find "PExports" )
if exist %MINGWBASEDIR%inmingw32-make.exe (mingw32-make -v | find "GNU Make")
if exist %MINGWBASEDIR%inmake.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%includew32api.h" (type "%MINGWBASEDIR%includew32api.h" | find "__W32API_VERSION")

:_end
PAUSE

)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As suggested by the bug report discussion linked in the comments, Microsoft's printf functions do not support C99. The mingw-w64 project provides alternative functions that may be used as if they were the normal C99 functions if the macro __USE_MINGW_ANSI_STDIO is set to 1 either before including any headers or on the command line. They support the standard %zu, %jd, etc. format specifiers that even the newest MSVCRT versions do not. You may invoke the function directly using mingw_printf, but it is usually easier to just define the aforementioned macro to 1 and call printf, etc.

It is worth noting that if you use Microsoft's snprintf, it will return -1 to indicate truncation if the buffer is not large enough, unless the buffer and buffer size parameters are NULL and 0 respectively, in which case the number of bytes that would be output is returned. C99 behavior is to always return the number of bytes that would be output if the buffer was sufficiently large, or a negative value if an encoding error occurs, and the mingw-w64 implementation seems to behave correctly according to C99.

And all you need to do to get all of this standard behavior is either #define __USE_MINGW_ANSI_STDIO 1 before any includes if you use any of the printf functions or simply add -D__USE_MINGW_ANSI_STDIO=1 to your compiler invocation.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...