Why I prefer C99 (per
n1256.pdf) versus C11 (per
n1570.pdf)?
Instead of bringing portable, widely-implemented features like
getline(), the standards committee was stuffed with Microsoft stooges who instead of furthering the C programming language, furthered the schemes of Microsoft by introducing the entirely unneeded Annex K. In other words, instead of getline(), you now have the "safe" fgets_s() instead.
None of the wide-character internationalization support got any enhancements, either. They are not needed, after all, because Microsoft does not actually support locales (without proprietary extensions) anyway.
(I was really hoping for
getline() and
getwline() to get standardized, because those two alone, taught to newbies, would remove a whole slew of typical bugs and inane limitations made by new C programmers. As it is, almost
nobody localizes their C programs anymore; the standards committee has made it clear who commands it, and what direction it will be dictated in. A big reason is that standard code that
is supposed to work even on Windows, doesn't, when the Windows' user locale uses UTF-8. Simply put, even after stuffing the C standards committee with people on their payrolls, they couldn't tweak the standard enough so that their own limpy implementation actually follows the standard.)
The immensely useful
iconv_open()/
iconv()/
iconv_close() interface from POSIX did not get standardized, because Microsoft didn't want to implement it. To use it in Windows, one can install the
libiconv library to get the support; basically all other desktop and server operating systems already incorporate it into their C library. But because Microsoft doesn't, it won't get into the C standard.
Instead of standardizing the
atomic operations implemented by GCC, Intel Compiler Collection, and a host of other compilers (but apparently not Microsoft Visual C++, which is after all more important and equal than anything else) – noting that they were the second generation of such ops, the first being
__sync built-ins, that AFAICR were originated in ICC, not GCC –, they went with their
<stdatomic.h> approach, which may or may not provide some features (it is up to the implementation; although you can check it via the
__STDC_NO_ATOMICS__ preprocessor macro), because that is the easiest way to implement minimal atomics support for a C++ compiler.
In C11, variable-length array support became optional, because one vendor's C++ compiler has issues with those.
Instead of leveraging existing POSIX threads with decades of C use, the committee went with a new "standard thread" support
<threads.h>, whose actual compiler and OS support is unknown and iffy at best.
Instead of utilizing experience with POSIX clock_gettime() facilities, they farted out an timespec_get() whose support is, well, purely a guess. If you have ever written a benchmark or test program that uses both CLOCK_REALTIME and CLOCK_MONOTONIC clocks, you can immediately see why the timespec_get() interface really does not cut it.
Really, if we look at C11, the really good things it provided was the
_Generic() selection expression and the
_Thread_local storage class specifier!
Up to C99, the C standards committee had taken already implemented things with user experience finding them useful, and standardized them.
With C11, that changed. Microsoft had decided to use it for the same purpose it standardized OOXML: to eliminate the need of having to compete with actual C implementations, and to ensure their own single-architecture C++ compiler implementation would suffice. Simply put, they threw the C standard under the bus, because they had the money, and they thought it would help their business.
Today, if one wants to write portable C code, Windows environment is right out. Even their locale support and terminal UTF-8 input/output won't work without using Microsoft-only proprietary extensions. You will need to use
predefined compiler macros to write Windows-specific code selected via preprocessor directives at compile time, if you do anything more complicated than a "Hello, world!" program. I'm sure Windows-only developers find this perfectly acceptable, but me, I do not want to be slaved to a single vendor. If a tool tries to restrict the portability of my code (like ICC did and does at runtime to code running under AMD processors), that tool goes out the window.
So, for portability and functionality, POSIX C (IEEE Std 1003.1-2008) and C99 is still the best bet. Not perfect by any means, but the best fit, for now. C11 and C18 could have continued the path that C99 started from C89, but instead, basically twisted the C standard into furthering the goals of a single vendor. As I understand it, C18 doesn't even add anything to C11 anymore, and is simply a collection of errata (because the day Microsoft gets something right the first time, is the day hell freezes over).
Okay, why the vitriol against Microsoft? It's not, really; it just happens to be the vendor that did this to the C standards committee,
which allowed it to happen. If it had been Intel or Pathscale that did it (AFAIK IBM don't have their own proprietary C compiler anymore), I'd be equally disgusted with them. I'm angry at the entity that did this to the C standard development process. Microsoft today is, I believe, quite different as a company, but standards development stuff moves slowly, and it may be impossible to undo the damage done. There may not be sufficient interest to even try.
There is still hope that POSIX C continues to develop, although it remains to be seen. One can read IEEE Std 1003.1-2017 online
here, and the list of C functions and interfaces is
here.
Please do realize that I am looking at this as someone who really appreciates good tools, and gets immensely disgusted when someone fucks up the future of an existing tool. I feel the same way when a physical tool manufacturer sells their brand to a low-cost manufacturer, who exploits the brand for increasing short term profits. This can happen even during the lifetime of a product – sadly common with computer electronics, actually, except that none of the manufacturers have a particularly good reputation anymore.
I don't care if it is C, or something else; my attitude depends only on it as a tool for solving problems, or implementing other tools. If you feel that everything you do is already dependent on Microsoft – or some other single vendor, like IBM, who now own Red Hat and have immense (and not altogether positive, in my opinion) say in the direction desktop and server Linux operating systems (i.e., those running the Linux kernel) will take in the future – then good for you; my reasons here will be irrelevant to you, and you can safely ignore them. But, if you are someone who has been in the software business for three decades, give or take, and don't want to be dependent on a single vendor because they will eventually fuck you over, you'll understand why the direction change between C99 and C11 has reduced my expectations from the C standards committee to zero.
I guess I should apologize for the rant, but I don't wanna. Every point above is something that I have seen bite someone else besides myself. The locale support and getline()/getwline() facilities are a particular sore point, because even MS actually implements them in their base "C" library; but as it is, they are practically forgotten in current C software projects. That angers me, because it leads to bugs (buffer overruns) and inefficiencies or artificial limitations, that would have been so easy to avoid otherwise.