i am using gcc compiler and the command line is
{gcc 'hellowo.c' -o 'hellowo.exe' -Wall -g -O2 -static-libgcc -std=c11 -fexec-charset=GBK}
and the edtion infomation is
gcc version 8.1.0 (x86_64-win32-seh-rev0, Built by MinGW-W64 project)
when I try
#include <stdio.h>
int main(void)
{
float float1 = 64.25f;
printf("%zd\n",sizeof(int));
printf("%a",float1); //float1=64.25f
return 0;
}
the compiler warns me:
hellowo.c: In function 'main':
hellowo.c:6:12: warning: unknown conversion type character 'z' in format [-Wformat=]
printf("%zd\n",sizeof(int));
^~~~~~~
hellowo.c:6:12: warning: too many arguments for format [-Wformat-extra-args]
hellowo.c:6:12: warning: unknown conversion type character 'z' in format [-Wformat=]
hellowo.c:6:12: warning: too many arguments for format [-Wformat-extra-args]
hellowo.c:7:12: warning: unknown conversion type character 'a' in format [-Wformat=]
printf("%a",float1); //float1=64.25f
^~~~
hellowo.c:7:12: warning: too many arguments for format [-Wformat-extra-args]
hellowo.c:7:12: warning: unknown conversion type character 'a' in format [-Wformat=]
hellowo.c:7:12: warning: too many arguments for format [-Wformat-extra-args]
however the output is
4
0x1.010000p+6
why this will happen, i am using a example of C primer plus to study on my own
It is so strange that .exe can work well and my program can be compiled successfully.
i try modify %zd to %zu,("%zd" statement is a example of the C primer plus)
still have the warning:
hellowo.c:6:12: warning: unknown conversion type character 'z'
in format [-Wformat=]
printf("%zu\n",sizeof(int));
^~~~~~~
hellowo.c:6:12: warning: too many arguments for format [-Wformat-extra-args]
hellowo.c:6:12: warning: unknown conversion type character 'z'
in format [-Wformat=]
hellowo.c:6:12: warning: too many arguments for format [-Wformat-extra-args]
why will Mingw-w64 gcc compiler generate wrong warning about the format of %zd and %a?
This is an incomplete answer.
The printf
function and the formats it support are not implemented by your compiler. They're implemented by the runtime library. In the case of MinGW, the compiler is a version of gcc and the runtime library is, if I'm not mistaken, the one provided by Microsoft for Windows.
The gcc compiler can also warn about printf
format strings that it thinks are incorrect, for example if you try to use %s
to print an argument of type int
. It has to make some assumptions about what the runtime library supports. Typically it just follows the rules of the C standard. But with -std=c11
, I'm surprised that it would complain about %zd
and %a
, which have been valid C since C99. (Some versions of Microsoft's runtime library might not support them, but that shouldn't affect the compile-time behavior.)
The bottom line is that your compiler has decided, for some unknown reason, that it doesn't recognize those formats, but the implementation of printf
in the runtime library handles them correctly. There's a mismatch somewhere between your compiler and your runtime library. gcc is probably using some heuristic to guess that certain formats introduced in C99 are not supported, and it's guessing wrong in this case. Perhaps Microsoft updated its runtime library relatively recently and gcc hasn't caught up with the change.
The warnings shouldn't affect the behavior of your program once it's compiled and linked.
Incidentally, the correct format for a size_t
value is %zu
, not %zd
, since size_t
is an unsigned type. %zd
is likely to work in this case, but use %zu
anyway.
I'm able to reproduce the problem with x86_64-w64-mingw32-gcc.exe
(version 7.4.0) under Cygwin. Removing the -Wall
inhibits the warning.
You can avoid the problem by passing the option -D__USE_MINGW_ANSI_STDIO
to gcc. This causes it to use a different implementation for printf
.