Frederick said:
If we look at a programming language such as C++: When an updated Standard
comes out, everyone adopts it and abandons the previous one.
Right, because C++ is a language in which there is active interest in
continuing to improve the language. From what I've read of the new C++
standard, the addition of "auto" alone seems to make the standard
update worth it.
It seems though that things aren't so clear-cut in the C community. It
would seem that C99 is the most up-to-date Standard, but far more people
seem to be working off the C89 Standard.
Well, there are basically no C99 compilers and there is no demand from
users.
Could someone please explain to me why this is so?
The value of the difference between C99 and C89 is basically
uncommunicatable to programmers. That's because the value of the
difference itself is so minor, and because programmers are more willing
to move in the direction of other languages than to invest more time in
learning subtle differences in the new standard.
C is a language whose problems are paramount and staring everyone in
the face. But C99 basically addresses none of these problems over C89.
The rise of the importance of cryptography as a field points out two
problems with the C language: 1) No simple way to express a high-word
multiply operation (even though the vast majority of CPU architectures
do support this with direct, and often highly accelerated hardware
support), and 2) Non-determinable integer scalar sizes, that are not
enforced to 2s complement. The crypto community responds simply by
ignoring the standard and instead uses de facto standards (long is
exactly 32 bits, all integers are 2s complement, right shift retains
the sign of signed integers, etc.) C99 did not address this problem.
Java and Python do.
But the big elephant in the room is the extreme fragility of the C
language with respect to erroneous behaviour. The language is littered
with undefined behavior, and basically embodies buffer overflows as
practically standard usage. The standard library includes functions
that are not practically implementable in re-enterable ways (many of
these have been addressed in TR 24731 (and also in the latest
Bstrlib)). Any library function which takes multiple pointers assumes
no aliasing, otherwise leading to UB (which C99 did nothing but
reaffirm more explicitely through syntax). In very large programs with
standard programmer error rates, heap corruption is often undetected
and generally leads to anomolous behaviour that is hard to trace back
to its source. This leads to a standard condition called "bit rot"
(long running and large programs eventually just crash for "unknown
reasons"). Even simple things like a heap memory usage count for
detection of memory leaks are unavailable except via expensive and
platform specific tools.
C99 doesn't address these problems, though they are addressed by other
languages. As a counter to this point, it is commonly claimed that you
*NEED* to go to another language if you want these features. This is
ridiculous on its face, as it is very common to see these problems
solved in the C language in platform specific ways. Keep in mind that
the standard committee has significant representation by compiler
vendors. This is an important point, because we can see that the
standard was updated more with the needs of the compiler vendor in
mind, than users of those compilers.
C99 did add 1) complex numbers, but you can scan this newsgroup to give
you a rough idea of how relevant that is, 2) restrict, which is very
useful for some performance scenarios, except where the compiler can
internally deduce the attribute (which is actually quite common,
especially for compilers that support constant propagation) but more
commonly is just used as an unenforcable rubber stamp for the
assumption of no-aliasing in standard library functions, 3) variable
length arrays, which is just redundant with the common practice of
using the struct hack (why not just expand the standard to say that the
struct hack is not a violation of the standard?) 4) arbitrary
positioned variable declarations, which serves no relevant purpose
other than some typing convenience or cosmetic effect. Big changes to
the compilers that do not correspond to any real user need.
C99 also added curious neutral features: // comments and stdbool.h, for
example which you can take or not. I don't see the big deal either way
-- they are entirely cosmetic.
And then that are the actually useful things that were added: 1) More
precise floating point, 2) stdint.h (its not determinstic like Java,
but at least programmer can have some idea of what kind of integers
they can use), 3) va_copy, which was just an obvious missing function
which is the only possible way to iterate through a va_list in multiple
passes. Unfortunately, all these are generally addressed simply with
platform specific usage. I.e., you can just assume you have IEEE-754
FP (which most platforms support), you can just know what the integer
properties of your platform are, and on many systems, copying va_lists
can be done just with a direct = operation.
So as we can see, C99 just doesn't add enough useful stuff that people
need, whereas other programming languages do. So C99 just isn't
compelling to users.
Many compiler developers *started* moving towards C99 incorrectly
thinking that users would flock to C99 just as they did to C89. When
it became clear to them that users just couldn't possibly care less,
they simply stopped. The result is we have a number of compilers with
"half-way" support for C99 (technically meaning that they are actually
not compliant with *any* standard) but which will never be completely
compliant.
The most explicit demonstration of this is when Microsoft, aware of the
fierce competition for developer mindshare with gcc which seemed to be
moving in the direction of complete C99 support, openly declared they
would not support C99 due to non-existent developer demand. This had
all the earmarks of yet another MS PR fiasco -- gcc would get complete
C99 support, MS developers would balk and complain about the lack of
C99 support, and MS would be forced to backtrack and throw resources
into supporting C99. Of course none of this came to pass, and it
obviously never will (keep in mind that a very similar fiasco happened
to them regarding proper C++ support, and MS *was* forced to support
the correct their compiler to support the C++ standards.) In fact, MS
has so much contempt for C99, they are proposing changes to the next
standard (via TR 24731) without any commitment to supporting C99, even
though you would imagine it would be a technical prerequisite for
supporting their own proposals.