The things that made C successful are rarely recognized even by its fans, but much moreso by its critics and competitors. Things it is most criticized for are among them. They have made C hard to unseat. Too-easy conversion between arrays and pointers is one such criticism, but such conversion was essential to its success.
C++ succeeded not just because it can call C libraries -- most languages can -- but because it retained every advantage C has, even those that few recognize. C++'s STL is a success because it built on what made C a success, deliberately. Alex Stepanov, anyway, understood. Most STL components are really just examples.
Today we are locked in battle against C's weaknesses, particularly in how easy it is to exploit C programs. We lose that battle when new languages leave behind what made C successful. Too-easy accidental conversions bad; deliberate conversions possible, good.
C got various other things subtly right, too: manifestly enough to make up for its blatant failings. If you would displace C, it is much more important to retain its strengths than to fix its flaws. You can do that without understanding by copying. Retaining strengths while leaving behind flaws requires understanding, which has proven too hard for most.
> C got various other things subtly right, too: manifestly enough to make up for its blatant failings. If you would displace C, it is much more important to retain its strengths than to fix its flaws.
I agree. I wonder how feasible it is to separate the two, though. Not because it seems as if there is some unavoidable trade-off to be made (if that was it then somebody would have found a relatively crisp definition of said trade-off). I suspect that it's best understood as an emergent phenomenon.
Consider the LINUX KERNEL MEMORY BARRIERS readme [1], which states very clearly: "Nevertheless, even this memory model should be viewed as the collective opinion of its maintainers rather than as an infallible oracle". And yet some people persist with the belief that such an Oracle must really be possible. Oracles are abstract concepts.
C doesn't persist despite its contradictions. It persists because of them.
I'm not claiming that this is good or bad. Just that it's the simplest explanation that I can think of.
Stepanov used a lot of APL, Lisp and Smalltalk inspiration to create the STL, originally implemented in Ada 83 generics, and then thanks to Bjarne ported it to C++.
There is a quite interesting session from talk done by him at Adobe, where he mentions his inspirations.
You misrepresent history: Stepanov implemented STL first in Lisp, then in Ada. Both were manifestly inadequate. Stepanov openly despised "OO gook", and lamented that "begin", "end", and operators ++ and * had to be class members until partial specialization finally made that unnecessary. (Now we have std::begin and end.) Partial specialization was added to C++ specifically to make STL more practical.
C++ proved adequate. But C++ compilers of the time were not; all of them needed massive improvement to usefully build programs that used STL. (It took many years for Microsoft to get there; STL implementations obliged to work under Microsoft compilers were badly crippled until after C++11 came out.) But no other language was up to the job.
Bjarne did not motivate porting it to C++; the language did. Bjarne helped, but Andrew Koenig might have helped more.
Too-easy conversion between arrays and pointers is one such criticism, but such conversion was essential to its success.
Could you elaborate on this point? Walter Bright famously wrote [1] that C's biggest mistake is that it implicitly degrades arrays to pointers when you pass them as arguments to functions. Do you have a rebuttal to his piece? I am not a C expert so I honestly don't know what could be wrong with his proposal.
C++ succeeded not just because it can call C libraries -- most languages can -- but because it retained every advantage C has, even those that few recognize. C++'s STL is a success because it built on what made C a success, deliberately. Alex Stepanov, anyway, understood. Most STL components are really just examples.
Today we are locked in battle against C's weaknesses, particularly in how easy it is to exploit C programs. We lose that battle when new languages leave behind what made C successful. Too-easy accidental conversions bad; deliberate conversions possible, good.
C got various other things subtly right, too: manifestly enough to make up for its blatant failings. If you would displace C, it is much more important to retain its strengths than to fix its flaws. You can do that without understanding by copying. Retaining strengths while leaving behind flaws requires understanding, which has proven too hard for most.