Search code examples
cgccmingwgcc-warningformat-specifiers

How to get MinGW GCC to recognize the %zu format specifier for size_t?


An image is worth a thousand words:

Microsoft failing C developers for decades

I know how to work around the problem. But how do I fix it in Microsoft, so that I don't even get the warning ?

EDIT:

  1. contrary to what others have been pointing out in the commments, this is specific to Microsoft system. I can run the exact same code on a linux machine, use it in the same version of VsCode with the same configurations (tasks.json and properties.json), with the same version of gcc, and I won't get these compiler warnings.
  2. the C standard I'm using is c17.
  3. trying to use format specifiers like "%z" (or even "%ll") in format-dependent functions (like printf and scanf) will trigger format compiler warnings, even in a fully updated (as of 08/2021) Windows 10 OS, with the latest mingw-64 toolchain (specifically, gcc 8.1.0 - which is the compiler being used here).
  4. the "compiler error" shown in the image is, in fact, just a format warning being treated as an error (to quote the compiler: " [-Werror=format=] ")
  5. thanks, "@the busybee". You tried to address the issue. It is, indeed, a nice work around, but it would affect development compatibility.

EDIT 2:

After running into format incompatibility problems that caused actual unexpected bugs (and after a terrible experince using GDB's advanced features on Windows, as well), I just decided to ditch out GNU for good on Windows. For C cross-platform development on a Windows machine, I'm using Clang now. So far, I'm 100% satisfied with the decision. Thank you everyone who took their time to help me out.


Solution

  • It's worth pointing out what the fundamental problem is here, namely: a giant, flagrant violation of the "don't repeat yourself" principle. We have a library function, printf, which at run time is going to parse its format string and try to print some stuff. And then we have a completely different piece of code in the C compiler, which is going to parse the same format string at compile time, and warn the user about potential problems.

    With MinGW under Windows the problem is compounded by the fact that the two parsers are written and maintained by two completely different sets of people with no connection whatsoever between them. (Under Linux, at least, there's plenty of coordination between the folks who work on gcc and the folks who work on glibc.)

    So it's not too surprising that there's not perfect agreement between the two parsers as to what's accepted. (Indeed it would be a miracle if there were perfect agreement.) The answers to this question describe at some length how imperfect the coordination was in 2012, and here we are 10 years later and it's still not perfect.

    Imperfection being the name of the game, there may not be a perfect solution. I have to believe that, in 2021, Microsoft's C run-time library does support %zu. But if the latest version of gcc built into MinGW hasn't caught up to this fact, if it is still warning that the z modifier is unsupported, there may not be much you can do. You can send a bug report to the MinGW folks, and they may act on it eventually, but meanwhile you've got code you need to compile today. You could turn off -Wformat, but you probably don't want to (as indeed I wouldn't), because you probably want -Wformat to keep checking for other mistakes you might make.

    I'm part of a group that maintains a large, mature, cross-platform codebase, and although it's an ideal solution that I'd desperately like to use, we still don't routinely use %zu, because we still can't be sure that every compiler and every run-time library we use agrees on it.

    I'm not saying this to suggest that you abandon %zu also, but merely to express my sympathy: it's still absurdly difficult, even in 2021, to printf size_t values safely and portably.