A History of C Compilers – Part 1: Performance, Portability and Freedom
thechipletter.substack.com
thechipletter.substack.com
Within a year other compilers started doing DFA.
The article also neglects Zortech C++, the first native code generating C++ compiler. ZTC++ was the catalyst that made C++ a major language, as the PC was where 90% of the programming was. Before ZTC++, C++ and Objective-C were neck and neck, judging from the volume on comp.lang.c++ and comp.lang.objectivec. With ZTC++, the volume of the former exploded, and Objective-C disappeared into oblivion (later resurrected by Apple for a while).
https://github.com/dlang/dmd/blob/master/compiler/src/dmd/ba...
I've also written a Java compiler (not from scratch) and a Javascript compiler/interpreter, and designed the ABEL (Advanced Boolean Expression Language) PLD compiler.
if not, i think tiemann beat you by a bit there, though i agree that zortech was more influential throughout the 80s and 90s
https://gcc.gnu.org/releases.html says the first version of gcc to include g++ was 1.15.3 on 01987-12-18. unfortunately it doesn't seem to be preserved in https://ftp.gnu.org/old-gnu/gcc/ where the oldest version present is gcc 1.23 from 01988-06-26; possibly there's a comp.sources archive or something?
It comes down to whether you consider a beta a release or not.
I don't know if Mike Tiemann wrote his own code generator or not. ZTC++ was written entirely by myself, from preprocesser to object file.
according to that page, there were four more numbered versions of gcc before april, but i don't know enough to say whether they were beta-quality or not; i didn't start using gcc myself until four years later. but if you were on the net at that time you could get a copy of g++, beta or no, while zortech's product wasn't available yet at any price
There were also a bunch of commercial c compilers, all of which I've forgotten.
gcc was the lowest common denominator compiler, with the benefits and drawbacks of being in that position.
In any case gcc won the *nix compiler wars because it was free and easily accessible. Getting a license for the commercial compilers took work and/or funds, and the latter was something most unix users didn't have.
During the UNIX freebie days no one cared about Stalmman's freedoms.
After Sun being the first UNIX vendor to split UNIX into multiple SKUs, for developers and users, then GCC suddenly became relevant after all.
For languages like Ada, this was even worse, because SunOS/Solaris SDK only contained traditional UNIX compilers. For something like Sun Ada compiler, it was extra.
From 1996-1999, the stable choice on both speed and reliability was the GNU one.
https://pages.cs.wisc.edu/~blbowers/fuzz-2001.pdf
FVWM ran circles around MWM or CDE itself about speed. Rxvt was much lighter than an xterm, not everyone needed to plot Tek graphs. Even some late Irix users preferred JWM against the propietary options.
Nowadays, GNU's the slight bloated one, being Guix the 'essential' GNU distro, making lots of 32 bit machines without SSD's a crawling nightmare to install.
Meh, gcc 2.8 was buggy as hell on Linux/i386 by around 1998, as was gcc 2.95 up to 2.95.3. The issues with it are what led to the egcs fork which eventually replaced the original gcc branch. So it wasn't all sunshine and roses.
Interesting that you mention stability, exactly during the GCC vs egcs politics time frame.
Additionally, nowadays clang also ships alongside VC++, and is offically supported by Microsoft as well.
No one cares about their freedom until they are denied it.
Most GPL software won't survive its authors, even Linux kernel remains to be seen when Linus et al are gone, and it gets taken over by newer generations VC driven.
This ignores how much freedom the wallet requirement takes away.
Nothing related with Stalmman's freedoms.
https://web.archive.org/web/20120620103603/http://zedshaw.co...
> Why I (A/L)GPL
> I want people to appreciate the work I’ve done and the value of what I’ve made.
> Not pass on by waving “sucker” as they drive their fancy cars.
Anything other than AGPLv3 is really just transferring wealth directly into the pockets of the beggar barons.
Also, if you have a desirable app that they want to make money off, they have the ability to just reimplement it from scratch, or make a protocol-compatible equivalent, so the license does not matter in the slightest to them.
On the contrary, they cared plenty, because GNU freedoms let them have a usable, reasonable-quality (and sometimes high-quality) environment both as developers and as users, which they could otherwise not get unless they were rich or employed by a corporation (who would then have them do what it wanted, not what they might have wanted to spend their time on).
Which is how UNIX workstation market came to be, and how even Windows ended up with BSD code on the networking stack.
Before that, GCC was of interest particularly on platforms that didn't provide good CC - a lot more platforms with various quality of software - by comparison the big name workstation vendors that survived longer also had higher quality compilers.
When compiler suite was included by standard, GCC had much less of a benefit to many users (I think gdb actually might have driven more?)
> … Part 1 …
It's strange to go back to old-school function definitions:
main(argc, argv)
int argc;
char *argv[];
{
But a C compiler in only 40k, assembler in 20K, and linker in another 20K is a whole world of tiny software compared to what we use right now.sdcc can be used to cross-compile for CP/M from a modern PC, if you provide a crt0.rel and libc. I rolled my own and was able to port a few useful programs and utilities with it.
https://t3x.org/t3x/0/index.html
Pascal like language, compiles at Unix and to DOS and CP/M, it can be run under CP/M too. It can compile both binaries and bytecode.
I ran a faithful Ladder port natively under a GNU Unix 386, it's really good:
My greatest claim to fame was embedding a Z80 emulator in Unreal Engine, extending it with TCP/IP and VT100 emulation, and being able to connect to BBS's on the internet, and run Rogue, Zork and Wordstar along with most other Z80 CP/M software:
https://i.imgur.com/aSc9VGL.png
https://i.imgur.com/dd0Nzo2.png
https://i.imgur.com/Usjd4Vk.png
https://i.imgur.com/Y5aIjCi.png
https://i.imgur.com/rIY1he8.png
(yes I know color CP437/ANSI graphics was not a thing on 8080/Z80 CP/M. But it was not difficult to make it work and it looks pretty in Unreal).
(Removing the "-v" flag causes it to generate some submit files, with $$$ suffix, but I don't yet support those in my CCP.)
I'll try it on real hardware next week and if it works there I guess that'll be another fun bug to hunt down!
You are going deep!
(And it has to be said one of the reasons I'm interested is because I have a Z80-based single-board computer which runs CP/M natively which helps for testing things.)
fwiw i suspect implementing only ansi c function headers and declarations would result in a slightly smaller c compiler than implementing only the k&r style ones
http://www.cpm.z80.de/develop.htm
Worked first time to create a simple "Hello World" program, but many of the included examples fail to compile for me, with random errors:
RM.C: 20: String too long (or missing quote)
CP.C: 56: Curly-braces mismatched somewhere in this definition
I'll have to explore more thoroughly later, but thanks for the prod!I removed the includes from a few files, changed FILEs to ints, and added "#define EOF -1", etc, which let some more simple code compile & link. But it felt like those changes shouldn't have been necessary.
I guess the good news is the compiler ran without me having to add any new CP/M syscalls/bdos functions to my emulator - unlike hisoft which required that I implement "T_GET" (Get date and time) and a couple of other functions I'd been missing such as F_SIZE (For getting a file size).
I never said a word about CP/M, sorry.
Referring to my original comment that you replied to, I was talking about Turbo Pascal on DOS, which (DOS, not Turbo Pascal) did have EXE files, from early versions that I had used. But the TP version I mentioned could only create .COM files.
In fact, I remember the DEBUG utility was DEBUG.EXE, again from early DOS versions, although it was possibly DEBUG.COM earlier.
you posted that comment in reply to stevekemp talking about the c compilers he was trying on his cp/m emulator; maybe you clicked the wrong reply link
plausibly early versions of tp could only create .com files because they originally came from cp/m before being ported to ms-dog
> it was possibly DEBUG.COM earlier
yes, though the cp/m version was ddt.com, with a rather rebarbative ui reminiscent not of ddt but of teco
No, I clicked the right reply link that I meant to.
But I see the issue now.
Although his context was small sized compilers on CP/M, my (implied) context was not.
Mine was just small sized compilers, period.
My comment about TP 3 was in that context, and was not referring to CP/M. IOW, I was just saying, TP 3 was another small compiler (and I omitted saying that it was on DOS). I did not even know that TP had existed on CP/M, although I had used that OS briefly, before DOS, and had actually used a Pascal compiler on it, in a programming course I was attending. I remember the machine had those big 8-inch floppy disks. (1) But that was not the TP compiler, it was some other one, I don't remember which.
So I can understand why you thought I was talking about CP/M, and hence said that it had no EXE files.
(1) Or it might have been an MP/M machine, because I vaguely remember that we had to log in to it.
yeah, tp3 is great. there were a lot of pretty decent compilers for ms-dog; being able to address hundreds of kilobytes of ram (even if awkwardly) and having separate 64k address spaces for code and data really reduces the difficulty of getting a decent compiler running. the compiler scene for cp/m is fairly dismal by comparison
also, the 8080 and even the z80 were a lot less hospitable to c compiler output than the 8088. on many small processors, though not the z80, sdcc by default compiles everything that isn't specifically marke as __reentrant as non-reentrant, so your parameters and local variables are statically allocated; this isn't compliant with the c standard but is surely a better default tradeoff for the 8080 (which sdcc doesn't support) and probably for the z80 as well. see https://sdcc.sourceforge.net/doc/sdccman.pdf#page=49 for details
Sure was, in many ways. That's why it had so many hardcore fans, and why people still talk about it.
Speaking to your second paragraph, IIRC, TP 3 even had overlays, although I never used that feature, maybe because of being in the early stages of my career.
NP :)
Ha ha, yes.
The first edition of The C Programming Language book by Kernighan & Ritchie (the book popularly called just K&R) used those definitions.
The second edition (the ANSI C one) used the latter kind of definition, the ANSI kind, with both function arguments and return values having (mandatory?) types.
I remember I used to religiously use the latter kind from as soon as the C compilers I used, supported them.
> > I wrote GNU C++ in the fall of 1987, making it the first native-code C++ compiler in the world.
I thought Walter Bright's Zortech C++ compiler held that honour, but apparently [0] that was released 1988.
https://archive.org/details/byte-magazine-1983-08/page/n13/m...
"One that has survived is Lattice C, one of the most performant of the compilers tested by Byte. Lattice C was so good that it was licensed by Microsoft and sold as Microsoft C V1.0 before being replaced by Microsoft’s own in-house Microsoft C V2.0 compiler."
"The Microsoft C compiler has interesting historical roots. Although Microsoft itself works with C, this compiler is not a direct Microsoft product. Instead, it is an adaptation of the famous and highly regarded Lattice C compiler."
There are also ads like https://archive.org/details/PC-Mag-1984-09-04/page/n51/mode/... saying "Microsoft C compiler / Includes Lattice C and the MS Librarian".
I can't find info about v2 or v3.
Edit: https://winworldpc.com/product/microsoft-c-c/2x says "Microsoft C 1.0 and 2.0 are a rebranded version of Lifeboat Associates Lattice C", so your doubt seems well founded.
> many insist that C is the programming language and that it will last forever
but it's 41 years later and c is #2 on https://www.tiobe.com/tiobe-index/, followed by c++, which is almost a superset. items #4, #5, and #6 use c syntax but are high-level languages, and item #7 is a redesign of c as a high-level language with different syntax by, in large part, the bell labs team that designed c in the first place. the #1 item is a high-level language that departs significantly from c syntax, but its almost-universally-used interpreter is written in c
41 years isn't forever but it's longer than computers had existed in 01983. so that's not a bad showing, especially given the thousands of programming languages that existed before c
______
(for future reference, the somewhat questionable ranking in the article i linked is currently python, c, c++, java, c#, js, golang, 'visual basic', sql, fortran, delphi/object pascal, assembly language, ruby, swift, scratch, matlab, php, kotlin, rust, and r.)
preceding c, there was a large, complex, portable algol-family language capable of handling a range of applications similar to c's, called pl/1. if you read 'the elements of programming style', from about the time c was born, many of the examples are in fortran; most others are in pl/1. gary kildall's first job working on microcomputers was at intel writing pl/m, a cut-down pl/1 for microcomputers, for which he wrote cp/m, from which ms-dos grew. ibm's database db2 is still written in a dialect of pl/1 called pl/x. one of wirth's first languages was a thing called pl/360, which was a version of pl/1 with extra low-level facilities for bootstrapping a better language
in short, pl/1 was very widely used and highly influential, even though it's almost forgotten today
and that's because it kind of sucked. compiling it required a large computer and even then was slow. even at the beginning, it was highly complex, so learning it took a long time. this got worse over time as more and more features were piled onto it, often as ill-advised efficiency hacks that then couldn't be removed, because people's programs depended on them. because it was highly complex, and there were a lot of surprising problems that resulted from complex interactions of all its complex features; compiler developers improved this situation significantly by working hard to provide better error messages, but that only diminished the problem rather than eliminating it
the preceding paragraph describes rust exactly as well as it describes pl/1, so if someone succeeds in producing a c-like small, simple language that provides enough of rust's unique advantages (which are indeed very compelling) i expect that it will replace rust
i doubt it will replace c tho
And this is why Rust is likely going to take over from C, not because it is the most C-like design, but because it can provide static safety guarantees.
There is considerable pressure, at least for internet facing code, to show that it is safe. And that is way to hard to do (and keep doing) for C.
Of course, somebody may come up with a brilliant design. But lots of organizations don't want to wait for that. They don't want to keep writing new code in C. And Rust has by now a mature compiler, a very active community.
don't conclude there isn't a better solution just because you haven't seen one yet
There are lot's of organizations that are not going to wait ten years. And we still have to wait for the language to be designed in the first place to suggest that waiting might be an option.
And 10 years from now, the people who have running Rust code are no going to switch to a language that is similar to Rust but may have a slightly better syntax or otherwise be closer to C.
this logically entails that x is not possible without those features. if x is possible without them, they are not actually needed to allow x. so, although you hadn't noticed, you were saying a lot about what is and isn't possible
there are lots of organizations still using cobol, and people who have running cobol are not in any hurry to switch, either. but i have the luxury of not having to care
But in my experience you need most of the other features. So any 'C with safety' will have a lot of the complexity of Rust. Though of course the syntax and defaults may be different.
At some point it becomes very subjective. Does a language need a UTF-8 string type, or is an array of 8-bit characters enough?
The research question would be, what is a minimal subset of Rust that still allows for programs that are commonly written in C to be easily written in this subset.
Some things, like the tuple type, or 'if let' can be removed, but is it still convenient to write programs without them? Closures are a bit tricky to see if they can be removed.
In any case, C struck a very good balance between being small and powerful. In my opinion Rust strikes a similar balance. Rust is a lot bigger, but it gives powerful tools to write reliable code.
If we compare C and PL/I then obviously the syntax differences between C and PL/I are mostly based on the taste of the language designer. But there are a lot of features in PL/I that simply have no equivalent in the C language. Either because when C was design they no longer needed to be in the language or because the features are move to the standard library.
In particular I/O is something that lots of language have as part of the language and C doesn't. So it is in many ways obvious why C a lot smaller than PL/I without losing any power.
But now we go in the opposite direction. We know what the safety outcome should be. So we can make a list of things that need to be in a 'C with safety', even if we cannot predict what the exact syntax will look like.
> In particular I/O is something that lots of language have as part of the language and C doesn't. So it is in many ways obvious why C a lot smaller than PL/I without losing any power.
that's not why; often obvious things are wrong
Software tools used to be really expensive. I remember in the 1980's buying both Rational System's Instant-C and WATCOM-C (32-bit DOS compiler) each for many hundreds of dollars before switching to free Linux and gcc.
Instant-C was, at the time, a magical kind of product. It was basically a C interpreter that could resolve undefined symbols at runtime - run your program then write a function and continue if it was missing. You edited code by function rather than by file, so everything was incremental and instantaneous, a big contrast to the normal experience back then of kicking off a big build and practicing your juggling while it progressed..
I think at some point I also started using DJGPP, which pushed me toward GCC (and Linux).
And IMO the documentation was better written, too.
Must have been fantastic to debug when there was an unexpected interaction between pass 37 and 51.
“The 1401 FORTRAN compiler has 63 phases, an average of 150 instructions per phase, and a maximum of 300 instructions in any phase.”
The phases aren’t all what I would call a compilation phase, though. For example, phase zero:
“Phase 00 - Snapshot. Loads a snapshot routine into 350 positions of core storage. This routine lists a specified amount of core storage.”
no idea what happened to that company