1

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.

  • 6
    Welcome to Stack Overflow. Please read [ask] and *ask an actual question* - tell us what **specifically** you are asking about, *in text that you write in the body of the post*, [not as an image](https://meta.stackoverflow.com/questions/285551/why-not-upload-images-of-code-errors-when-asking-a-question). Also, do not use your question to vent about companies (especially since, as noted, you aren't even correctly placing blame). – Karl Knechtel Aug 23 '21 at 23:44
  • @RetiredNinja no, it works fine in Linux. It's when you try to compile in a Microsoft system, the runtime library that Microsoft implements doesn't recognize some pattern specifiers in some functions (like printf() and scanf() ) –  Aug 23 '21 at 23:46
  • He wants VS Code inrellisense to recognize the problem. I believe that Microsoft means VSCode – 0___________ Aug 23 '21 at 23:47
  • 1
    Does https://stackoverflow.com/questions/10678124/ help? Or https://stackoverflow.com/questions/59147875/ ? – Karl Knechtel Aug 23 '21 at 23:48
  • @0___________ no, the image clearly shows a compiler error message, not an Intellisense pop-up. – Karl Knechtel Aug 23 '21 at 23:49
  • @vitorhugo Microsoft does not implement any of gcc libraries. – 0___________ Aug 23 '21 at 23:49
  • 3
    This is not Microsoft's fault. It is, evidently, a shortcoming in MinGW, which is not a Microsoft product. – Paul Sanders Aug 23 '21 at 23:51
  • @KARLKNECHTEL *"so that I don't even get the warning?"* – 0___________ Aug 23 '21 at 23:51
  • 3
    In addition to using text instead of an image please use a subject that asks a question or describes the problem (rather than just rants). – kaylum Aug 23 '21 at 23:53
  • @KarlKnechtel thanks for the resources. I'm checking them out. I'll just say that it's a warning. the reason it is being treated like an error by the gcc is because I added the "-Werror" flag. Still, I don't understand why formaters like "z" and "ll" (long long) still trigger "Wformat" warnings. I think is due to the fact that the compiler uses a runtime library provided by windows (I would have the same warnings using Code::Blocks on Windows - but none of them using Linux (on whatever IDE)). How do I update the Windows library so that I don't get this warnings? Does anyone knows? –  Aug 23 '21 at 23:55
  • @0___________ there isn't a warning shown in the image, but I assume "a warning" (i.e., a *compiler* warning) was meant rather than "the warning". – Karl Knechtel Aug 23 '21 at 23:55
  • @PaulSanders thanks for your input. But, no, it's specific to Microsoft. When using the same version of the gcc in Linux, it's compiles without Warnings –  Aug 23 '21 at 23:57
  • Would you mind to delete the screenshot and copy the shell output verbatim, please? As you see in the comments, screenshots are hard to read and lead to misunderstanding. – the busybee Aug 24 '21 at 06:19
  • @VitorHugo If I'm understanding things correctly here, you have a *compiler* problem, not a *library* problem. Your library *does* support `%zu` — correct me if Im wrong — but your compiler doesn't realize this, and warns about it. So your need is not for an updated library that implements `%zu`, but rather for an updated compiler that doesn't wrongly warn about it. – Steve Summit Aug 24 '21 at 11:11
  • 1
    It is MS specific, when you compile on OS, it includes specific headers –  Aug 24 '21 at 13:19
  • Does this answer your question? [MinGW GCC: "Unknown conversion type character 'h'" (snprintf)](https://stackoverflow.com/questions/10678124/mingw-gcc-unknown-conversion-type-character-h-snprintf) –  Aug 24 '21 at 21:49
  • @KPCT first of all, thank you for taking the time to write your comments. Yeah, the post you're suggesting is good and I had already seen it (it has even been suggested here in this comment section). The thing is that the post is 9 years old, and provides no solution. Almost a decade later, we still have the same problem, unfortunately. Today I run into a bug caused by gcc on Windows not recognizing the format `%Ld`(long double), and printing out bad results. I just gave up and changed to the Clang compiler. Didn't change a single line of code, and everything worked out fine all of a sudden. –  Aug 24 '21 at 23:26
  • @KPCT the clang compiler, not only didn't have any trouble whatsoever with the formats, it actually gave me additional **USEFUL** warnings (with the same Warning flags I was using for the GCC) about security. So, that is it: the real "solution" is **not to use GNU at all on Windows** (I could go on and on about troubles with the GDB on Windows as well). Just use Clang for C crossplatform development, and that's it. –  Aug 24 '21 at 23:31

2 Answers2

3

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.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • yeah, that's basically it. The only thing to do regarding the triggering of the warning is really to just report a bug, it seems... but regarding "work arounds", yeah, @the busybee has suggested a very interesting solution, and I, myself, in the comments to his suggestion, had already pointed out others. thanks to you both. –  Aug 24 '21 at 13:15
1

MinGW uses the Microsoft runtime library by default, and so printf()'s format string is checked as the MinGW project thinks that Microsoft supports it. Apparently %zu is handled as not supported, which might not be necessarily true. (A quick check with MinGW64's GCC 8.1.0 on Windows 10 shows the warning, but works.)

However, MinGW also comes with a set of alternative implementations. To use them, prefix the function names with __mingw_ (e.g. __mingw_printf).

Depending on the nature of your project, you might want to globally #define printf __mingw_printf or use -D__USE_MINGW_ANSI_STDIO (which enables the MinGW versions of all the printf-family functions).

Another option to avoid the warning is to hide the format string from the compiler, for example by putting it in another module, or constructing it during run-time.

the busybee
  • 10,755
  • 3
  • 13
  • 30
  • thank you very much for your answer. It is definitely one of the "work arounds", but that one would make my code non-portable (another work arounds, which wouldn't affect portability, would be to just compile without the "-Werror" flag. I could also down-cast the `sizeof` output to `long unsigned`). I upvoted your effort anyway, because you really tried to address the specific problem in the Micorsoft system and get rid of the "compiler warnings", but can't mark it as solved, because of portability issues. I just wanted to know how to update the microsoft's format libraries. –  Aug 24 '21 at 10:43
  • 1
    Well, portability is always a matter of how small the common set of features is. "%zu" seems not to be part of it. ;-) However, you could use `#define` conditionally, or `__USE_MINGW_ANSI_STDIO` will not influence other target systems. – the busybee Aug 24 '21 at 11:19
  • thanks. I think you bring up very good points. The "z", or even "ll" ( ` long long` ), format modifier should be crossplatform, secure and simple to implement; how they're not, simply baffles me.. Since C99, they're standard format modifiers, and the `sizeof` function is fairly commonly used. I think because some of the "work arounds" (like the downcast) are so simple to use, that this just went under the radar.. I guess (?). Whatever, bug reported. Thanks for your time. –  Aug 24 '21 at 13:24
  • 1
    *Apparently `%zu` is not supported.* Not true - MinGW is broken here. [MS supports `%zu`](https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-160): "`size_t z or I (uppercase i) d, i, o, u, x, or X`" That's not exactly hard to find, either: https://www.google.com/search?q=msvc+format+string – Andrew Henle Aug 24 '21 at 23:47
  • @AndrewHenle it's GNU running on Microsoft, but other compilers (Clang and MSVC) work just fine. The problem of ignoring warnings is that in C you'll end up running into unpredicatable behaviour. Ignored a warning regarding `%Lf`, and ended up with buggy code after compilation.... rebuilded and recompiled the same program with Clangm, and, besides getting no -Wformat, the code run just fine. Didn't change a single character in the source files. Mingw-64 is definitely broken on Windows (GDB won't even allow for "record" or "backstep" functions, or even "tui mode").... just ditched it. –  Aug 25 '21 at 22:55