Let's compile like it's 1992 (2014)
fabiensanglard.net
fabiensanglard.net
Hey, I think I see a pair of @'s
But while most of our tooling for Software Engineering is pretty archaic. I think there is a tooling revolution going on now, especially with new languages: autoformatters, graduation typing, memory ownership checkers, etc. I feel like as an industry we are slowly starting to take tooling seriously.
Turbo Pascal 6.0 (for DOS) was my first real exposure to programming (not counting the various BASICs and a short stint learning 6502 assembly) and led to my teenage self writing a bunch of "IGMs" for Legend of the Red Dragon [0], a BBS game. Unfortunately, just as I started teaching myself C, I scored a copy of Visual Basic 3.0 and it was all downhill from there.
It's really cool to see this game I played 20+ years ago and think about how technology has come. I can't imagine what the next 20 years will bring.
Wrong. The Pascal compiler had had years of optimization done to it and their C compiler was a 1.0 product. My programs ran at half the speed of everyone else's.
Keep in mind that the C++98 mainly standardized what compilers were already doing.
A Few years ago I managed to copy an old DOS diskette onto DOS VM and compiled and run a space invaders game I wrote. TC said it compiled but just kept returning me to the IDE when it executed! I eventually tweeked the VM speed down by about 100 at which point I saw the very fast invaders move to the bottom in about 2 seconds and kill my defender!
Not surprising. As far as I know, Pascal doesn't have anything remotely as hostile to efficient compilation as the C preprocessor (oh look, changing that one constant in a header file rendered your entire project out-of-date because the compiler can't prove that it doesn't make arbitrary memory layout and AST changes in every file that indirectly #includes it).
You wouldn't get such compilation windows with Pascal derived languages using their module systems.
The proof being that with VC++2017 using the incremental linker and C++ experimental modules, one also gets more human friendly compilation times.
https://blogs.msdn.microsoft.com/vcblog/2016/10/05/faster-c-...
The Microsoft blog is only about the incremental linker, modules would speed it up even more.
But even in Turbo/Borland/Free Pascal modifying a unit means that you have to recompile the other units that need that unit.
Actually I find those cascading of build dependencies quite productive.
Sometimes I wonder if Pascal variants had gotten more love from gamedevs (TP was my Unity), if they would be always coming up with tricks to speed up their build times or force reloading of C++ code.
Official SDKs and OS APIs written in C didn't help either too, although that was a minor issue. But still created friction.
Of course with Free Pascal that isn't the case anymore, FPC is the compiler with the second number of supported platforms (after GCC) and architectures, but the stigma and public perception of the language still prevails (for example many things that people laud D and Rust for are things that Free Pascal did for years).
Wirth-style compilers also often don't even build an AST. Wirths own compilers called functions in the code generator module directly from the parser. Which again was something he could easily do because the languages were designed for single pass compilation.
Experienced the same thing when PC's came out with the 'Turbo' button. I recall having to turn off Turbo many times to make games semi playable again on new PCs.
I had no idea if my executable would be bigger or smaller than his, but I didn't want to put effort into the contest until I knew I was behind. As it turns out, it was about half the size of the C executable and he never asked for a round two. My friend was very frustrated that day.
Fun day.
EDIT: I did some research. They were actually at best 286 machines. The computer lab had those IBM PS/2 all-in-ones with MCGA graphics.
The compiler is part of the IDE, not some external process that needs to start from a blank state for each file, needing to read the same files over and over (which is what every other "IDE" does these days, similarly with the debugger which is usually running gdb at the background and some IDEs do not even bother to perform the builds themselves and instead using cmake or whatever - honestly it is as if people forgot what the "I" stands for) and it keeps compiled objects and libraries in memory and even uses the source code directly from the open windows's text buffers instead of having to save the file and load it from disk (although it does write the object and executable files to disk, it just doesn't do the unnecessary roundtrip for compiling the source).
How many passes is it doing? I suspect they aren't doing much optimization then? Maybe they patch in differences in the ASTs at the IR level and work from there?
I love tcc, in fact I added a firmware instruction translator to 'JIT' AVR code to simavr a few weeks ago. Takes a AVR binary, translates it to C, and compiles it on the fly with libtcc to run it :-)
That is unholy, and glorious.
If you look closer, you can see I've actually repurposed the main interpreter core, and uses a GNU awk (of all thing) to extract each opcode emulation 'meat', converts it to a string to and that string is used by the translator to generate the C for tcc...
I haven't tried TCC, i think i tried at the past but it was missing some libs.
I suspect the difference is negligible in practice. In both cases, the files are likely to be cached in memory after they're read the first time, so you're not really reading it over and over.
From a performance standpoint the win comes from not having the compiler start from a blank state for each file but keep the compiled objects in memory and only update the changed files. I suppose a modern reimplementation of that idea (that has more memory to spare, after all the official BC++5 requirements were 16MB of RAM) would be able to have a more fine-grained approach.
https://gcc.gnu.org/wiki/IncrementalCompiler
https://www.reddit.com/r/cpp/comments/59n8ya/what_happened_t...
I don't know how much effort is poured into these projects. There are some clang based servers like ycmd and rtags, but these are used for linting, refactoring and search (so no incremental compilation).
But yeah, i do not see much effort going on in improving these areas. I think people are just used to "patchwork IDEs" and find them good enough.
Yes, I remember it being very pleasant when borland C++ crashed after running your application, losing your unsaved work.
edit: that was on windows 95/98 time; so it is more likely that the application crashed the whole OS.
But at the same time it can be a convenience if you dont want to save but instead make a small change to try something out.
I'm pretty sure Borland used to separate out the IDE executables from the compilers and a couple of other tools tool. I don't have a copy to hand to prove this but I'm sure I used to occasionally invoke Turbo Pascal's compiler from the command line outside of the IDE (due to it being a separate .exe / .com) and I vaguely recall Turbo C++ having a similar design.
I also don't recall build times being that much faster then than they are now. But maybe that's more a symptom of myself compiling on budget hardware previously where as I can now afford better spec'ed dev machines (compared to the market average).
But you could take TURBO.EXE (ide+compiler+debugger) and TURBO.TPL (the library), put it on a floppy and work from there. Back when i was a kid, my process to start a new "project" was to take a blank floppy and copy those files (and a couple of units i was sharing) since i didn't have a hard disk. I still have a ton of floppies littered with turbo.exe/tpl pairs.
The Turbo C/C++ also needed only a single executable, tc.exe/bc.exe (depends on the version) and the include and lib directories.
This is the same with Borland C++ 5.0 i am talking about above, although that one also needs a bunch of DLLs too. Since i don't want to break my installation, i only renamed the bcc32.exe and bcc32i.exe to something else, run the IDE and built my engine. As i expected it worked. Although the fact that you can make modifications and have them compiled without saving the file is also an indicator.
Turbo C was like that, but not the first few versions of Turbo Pascal.
The whole goal with Turbo Pascal was to have everything in one small program so you could code/compile/test as fast as possible. It used a one-pass compiler and didn't have a heavy linker. It was fast even on a 8088. Anders Hejlsberg was the original author of Turbo Pascal (yes, the same guy from MFC, J++, C#, TypeScript...)
The original TURBO.COM file was very small. This was great because you could fit the whole thing on one floppy disk including your own code. No swapping floppies. Plus it was only $49.95 USD!
Pascal compiled way faster than C because there was less to do. No #includes to chew through. But Turbo C was even a fast compiler back then. A hundred thousands of lines per minute according to the ads. Imagine how slow I found DJGPP and other compilers when I finally moved to 32-bit programming.
Maybe you meant Windows Forms? AFAIK MFC was made years before Anders left Borland to join Microsoft.
The neat trick was debugging. Instead of tagging to object code with source-code line numbers, to break on line N, Turbo Pascal simply recompiled the source up to line N, and used the size of the output to match the instruction pointer in the debugged image. Move to next line? Compile one more line, and stop at the last produced instruction.
But these were tiny programs, written ab initio. No readline, no X, no network, no database. Hardly any filesystem. To do something akin to readdir(3) meant writing a bespoke function to call the DOS interrupt. Putting a menu on the screen required positioning the cursor in the video buffer and putting each character in successive locations, allowing for the attribute byte.
If Turbo Pascal was simple, it was also primitive. Much bigger C programs compile in the blink of an eye today. Complex programs take a long time to build today, yes. They did then, too.
So nowadays I only use Emacs for Clojure or when I happen to access an UNIX server box.
It was one of the most pleasurable experiences with "programming" since those Pascal times, and gave that feeling of being close to the code. I attribute it to fast compiles, no need for context switching (due to superb autocompletion), and everything just working well inside the tool. Documentation was also very good, and the huge API you're exposed gives a feeling of power (like I felt as a teen with computers, that I could do so much).
(My recent experience was Python, C (embedded too), Golang, and JS in the browser.)
That’s the reason why C#, or the language it was copied from (Java) are still popular when performance doesn’t have to be 100% perfect. Easy to use, very well documented and powerful, and reasonably fast.
EDIT: Found Turbo C++ 3.0 and TASM and these work just fine!
But sadly Wolf3D is real mode (maybe 16-bit?) and I got accustomed to the "luxuries" of 32-bit development on DOS under DJGPP
I'm still smiling.