2

Trying to build+run this simple C program in MinGW produces strange results

#include <stdio.h>
void main() {
    printf("%03d", 7);
};

If I build it with any standard-C compliance flags (-std=c89/99/11) the padding is ignored:

C:\>gcc -std=c11 a.c
C:\>a
7

Whereas in regular GNU C mode it works fine:

C:\>gcc a.c
C:\>a
007

Is this a bug in MinGW? Have I missed something? Or is the padding specifier really not a standard C feature?

For reference, here's the output of gcc -v on my system.


As suggested by 2501, the best workaround is to instead use MinGW-W64, which is actually a separate project from MinGW. It can still produce 32-bit binaries, despite the "W64" label.

Community
  • 1
  • 1
Cauterite
  • 1,637
  • 17
  • 24
  • 2
    Why is your `main()` `void main()`??? That's wrong in all of the standards you're testing I think. You should enable compilation warnings specially if you are learning. I never turn them off except when I build a release where it would be pointless to make the compiler work more. But normally in debug builds, always `-Wall -Werror`. I like to keep the compiler as happy as possible to prevent having to check for *silly* mistakes by myself. – Iharob Al Asimi Jul 19 '16 at 13:10
  • I deleted my answer since some people apparently beleive that It's wrong, although no one explained why. If it helped please let me know. But the downvoted answer is not "*useful*" so it's better deleted. – Iharob Al Asimi Jul 19 '16 at 13:20
  • 1
    Thanks @iharob, but your points aren't really the issue here. `main` can safely have the wrong signature since it's a cdecl function (caller cleanup) and the arguments aren't used. – Cauterite Jul 19 '16 at 13:24
  • It was wrong indeed and the generated assembly is almost identical in both cases. I wonder how that relates, to the standard specification. It looks like it is indeed related to the bug you mention in the comment to the "now deleted" answer about the macro. – Iharob Al Asimi Jul 19 '16 at 13:24
  • 1
    Apparently your compiler doesn't have the license to kill. – 2501 Jul 19 '16 at 13:25
  • `-fno-builtin` is not the solution, in case anyone was going to suggest it. I tried that already. – Cauterite Jul 19 '16 at 17:45
  • Here's one workaround that seems to do the job: `gcc -std=c11 -Wl,-u,_vprintf -Wl,--defsym,___mingw_vprintf=_vprintf a.c`. Apparently `printf` gets rewritten to `__mingw_vprintf` by the compiler, so with these linker flags we're forcing the linker to substitute `__mingw_vprintf` with the MSVCRT `vprintf`, which behaves correctly. Care should be taken though — I'm sure msvcrt.vprintf has its own set of pitfalls. – Cauterite Jul 19 '16 at 18:13
  • 1
    @Cauterite I suggest you install mingw-w64. It's like mingw but better, and doesn't have this flaw. – 2501 Jul 19 '16 at 19:23
  • @2501 thanks, that's good to know – Cauterite Jul 19 '16 at 19:44
  • @iharob: see [What should `main()` return in C and C++](http://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c/18721336#18721336) for details of why it _might_ be OK to use `void` as the return type for `main()` on Windows platforms — though it isn't clear-cut when using the MinGW compiler whether the runtime library used supports it or not (it is 'OK' with the MS compiler and runtime library). – Jonathan Leffler Jul 19 '16 at 21:14

0 Answers0