> And that’s why C is still the best language for systems programming
I think the only reason C is very popular for systems programming is that it allows you to do most of what you could do in assembler, but in an easier-to-work way. So basically C is an "acceptable, easier-to-use assembler", but far from ideal, because of the reasons you point out.
Honestly, the popularity of C itself is due to the success of UNIX, not due to any particular quality. On the other hand, the K&R "The C Programming Language" book is a classic, a well written book which surely does a great job of introducing the language.
But back then in the late 1960s, a new language called ALGOL-68 was specified, back then a very advanced language which had powerful features even for 2017. The problem is that nobody dared to implement the full language. CPL was a stripped down implementation of Algol-68, this was then stripped down even more to BCPL; then it was extremely stripped down to B (only one datatype), then Dennis Ritchie kept most of the syntax and added other data types and C was born. C was never designed from the ground up to be the best systems programming language possible; only to be able to work for Dennis Ritchie & friends' "toy" operating system, UNIX, a very stripped-down MULTICS.
I think the "UNIX-Haters Handbook" has a section devoted to C criticism.
> Honestly, the popularity of C itself is due to the success of UNIX,
I beg to differ. C was a fairly obscure language until MS-DOS came out. C turned out to be ideal for programming on DOS, and DOS programming was far and away the most programmed system in the world for a decade and a half.
MS-DOS also made C++ into a major language (via Zortech C++). When ZTC++ came out the penetration and popularity of C++ went through the roof.
(Yes, I'm tooting my own horn a bit here. But I honestly believe it is ZTC++ that got C++ its critical mass.)
MS-DOS made C and C++ into the juggernauts they became.
> I beg to differ. C was a fairly obscure language until MS-DOS came out.
On the early days of DOS, what was used the most was IBM-BASIC (and GW-BASIC) for users, assembler for games like Alley Cat, IBM LOGO for teaching, some games were made on FIG-FORTH even
Then borland brought Turbo Pascal which was hugely popular together with MS QuickBasic.
Meanwhile, and we're at 1986-7, a good amount of software was already made for the Unices, in C. I don't think anyone was doing C for DOS back then. My grandpa -a PC nerd- had a huge (200+) collection of diskettes around that era, which now I own, there are all sorts of compilers for the above languages, plus Fortran, Clipper, etc; but no C compiler. Even though he owned the K&R book.
First time i saw use of C on the DOS world was with Borland Turbo C++.
There were probably 30 C compilers for the IBM PC. Turbo C didn't appear until 1987, it was quite a latecomer. C was immensely popular on the C before then.
Borland produced Turbo C not to introduce C to the PC, but because C was so dominant on that platform. After all, why would they have done that after being so successful with Turbo Pascal?
Sorry but on my little corner of the planet, in the Iberian Peninsula, everyone was using Turbo Basic and Turbo Pascal, when not coding in Assembly for MS-DOS.
On the PC, C and C++ only started to be widely adopted as we started to code for Windows 3.x, due to the APIs being available as C instead of interrupts.
At the technical school I was attending, I was the outlier by having had the opportunity to get hold of Borland's Turbo C++ 1.0 for MS-DOS, everyone else couldn't care less.
Most Portuguese and Spanish magazines of the 80's and early 90's were full all imaginable programming languages for C64, ZX Spectrum, Amiga, Atari and MS-DOS. C didn't had a better spot on those articles than the other languages, quite the contrary.
Fellow Iberian HNers are free to correct my experience of those years.
In my part of the world, we used the Borland compilers for MS-DOS, Turbo C and Turbo C++. Turbo Assembler and Turbo Pascal was also popular.
Never heard of Zortech C++ before
Borland decided to develop TC++ because of the success of ZTC++. (I know some of the people involved.) Before ZTC++, C++ was a niche language, and Borland was having great success with Turbo Pascal. ZTC++ came out in 1987, and TC++ in 1990.
After the success of ZTC++ and TC++, Microsoft changed direction and decided to develop a C++ compiler, too. I heard (but was never able to confirm) that Microsoft had earlier been developing their own object oriented extensions to C called C*.
Coming from Turbo Pascal TC++ was a bit underwhelming. When I tried it didn't colour syntax, there was those weird #include and compin=ling felt so slow. So my first contact with C was pretty negative :\
TP was indeed a fine project. But it wasn't OOP (which was very hot at the time) and TP was very customized to the PC, meaning it had no penetration outside of DOS. TP died when DOS died.
TP's OOP was modelled after Apple's Object Pascal. It was an awkward ugly implementation that had e.g. slicing problems and weird initialization syntax, and was fairly quickly deprecated when Delphi came around.
I loved Object Pascal, and it was my introduction to OOP, literally.
As I had to give a class on OOP to fellow students at the technical school as exchange for having access to Turbo Pascal 5.5.
Never was a big fan of some of the Object Pascal changes made by Delphi's class model, specially the fact that it was a kind of lost the opportunity to introduce RC alongside those changes.
Which eventually lead to the schizophrenic model that RC would only exist for COM based classes, but not others.
RC only for strings originally, later dynamic arrays, variants and interfaces; I no longer recall if the legacy OLE automation classes did automatic RC, but I don't think they did (beyond explicit RC in constructor / destructor implementations).
I maintained the Delphi compiler front end for 6 years or so, adding closures, enhanced RTTI, a bunch of work on generics and 64-bit porting, and some other things that ultimately didn't see the light of day. I have a long list of things I don't like about the Delphi language, corner cases you only really become fully aware of when living with the workarounds they force on the codebase.
Overload resolution is an almost wholly unspecified mess, for example. It started out Java-style, but the definition of more specific isn't locked down, and everything from strong typedefs (type TFoo = type TBar;) to closures (MyFunc(methodRef) - do you mean to pass method ref or result of calling method ref), to ranges (are smaller ranges more specific? what about overlapping ranges?)... and don't get me started on all the different string types.
I followed some of your blog entries, hence my earlier comment. :)
The first time I went through the Turbo Pascal for Windows 1.5 manual I wasn't that happy to see PChar, let alone the other variants that came later.
Although it seems that in today's world, most languages end up with a jungle of string types, for every possible variation of Unicode, ANSI and C ABIs.
I eventually did the full transition from Object Pascal to C++, so I only used the very first versions of Delphi.
So in what concerned Windows development, I ended up moving from Borland to Microsoft compilers when Visual C++ 6.0 was released, which means I lack the experience how later Delphi versions evolved.
For big computers, C is good for systems programming because everyone else uses it and because of the titanic effort that has been put in to building really good optimizing C compilers. UNIX came along but when C killed pascal, IBM, Microsoft, everybody was on C's dick.
On small embedded computers, I think C is popular because it's so easy to build something that resembles a C compiler. The fact is, undergrad compiler classes almost build C compilers (some universities might actually go all the way.) You can almost build a yacc grammar that will read C and emit assembly. The small computer embedded vendors have a difficult problem, they need to provide tooling and they don't usually have giant piles of developers to sell to. So they dust off some abandoned "C compiler" they found in the gutter, add their hardware to it and call it good. At least that's my theory and I've seen some rough "compiler work" from some pretty substantial hardware vendors. In fact, if you're running a 16bit or smaller part or a weird part, I have yet to see a decent C compiler from a hardware vendor.
> You can almost build a yacc grammar that will read C and emit assembly.
I have looked at a lot of C parsers and compilers and have written a C to Lisp transpiler and this statement is ludicrously wrong. You cannot even parse C code with yacc because of typedefs. The grammar of C is context-sensitive. And this is after the C code has been preprocessed, something that also cannot be done with yacc.
C compilers are easy to port to different machines, but that is because C is a very poor language in terms of features and control flow constructs. For the limited amount of things that C gives you as a language it also comes with a huge amount of complicated baggage when it comes to implementation and corner cases.
I think the only reason C is very popular for systems programming is that it allows you to do most of what you could do in assembler, but in an easier-to-work way. So basically C is an "acceptable, easier-to-use assembler", but far from ideal, because of the reasons you point out.
Honestly, the popularity of C itself is due to the success of UNIX, not due to any particular quality. On the other hand, the K&R "The C Programming Language" book is a classic, a well written book which surely does a great job of introducing the language.
But back then in the late 1960s, a new language called ALGOL-68 was specified, back then a very advanced language which had powerful features even for 2017. The problem is that nobody dared to implement the full language. CPL was a stripped down implementation of Algol-68, this was then stripped down even more to BCPL; then it was extremely stripped down to B (only one datatype), then Dennis Ritchie kept most of the syntax and added other data types and C was born. C was never designed from the ground up to be the best systems programming language possible; only to be able to work for Dennis Ritchie & friends' "toy" operating system, UNIX, a very stripped-down MULTICS.
I think the "UNIX-Haters Handbook" has a section devoted to C criticism.