At my current dayjob, there exists a ton of code written over multiple decades, much of which is in Pascal and some sort of prelinking C. (The latter probably deserves its own post, but I don’t have the time to fully investigate it. After all, I am not hired as an archeologist. Headers stating copyright dates in the 1980s and lines like
if (!(dllFuncs.hDll = LoadLibrary("wininet.dll")) ) make it seem that once linkers did not exist, a thesis for which I haven’t found any evidence yet though.)
Learning Pascal, which is something you probably shouldn’t do these days, the good work of the Lazarus and Free Pascal people notwithstanding, is actually turning out to be a fine introduction into old-style C. My first interest started with the layout of Pascals
procedures if nothing is returned). Between the function declaration (which is very familier for C++ or Python people (especially typed Python people) and the function body exists the list of all variables used in the function (all, in addition to the function parameters). So while a function can allocate as many variables as it wants, they must be declared beforehand. I once read that Pascal compiles so fast because it is singlepass, this must be one of the things that enables that. In other words, before the function starts, the memory layout is completely known. Does that remind you of anything? Of structs! But with bodies. Which are classes. It actually makes sense. It does however make it a bit too tedious for my tastes. Even loop variables have to be declared this way, making reuse attractive, making bugs more probable…
Through Hackernews I came across a post covering possibly the worst C textbook ever written, and not surprisingly pointer abuse is at the heart of most of the damaging ‘advice’. I tried hard to understand to understand the first example (some context perhaps: I was raised on C++, and was eagerly awaiting C++0x goodies for a very long time). After a while I realized the first two lines were in fact a pre-amble to the function, I style I had never seen before but seemd extremely similar to Pascal! After some digging, this turns out to be indeed the way functions were declared in the dim mists of ancient C: exhibit A and exhibit B. Ha! Note that it’s actually a big difference between Pascal and C: in old-style C the type is absent in the function argument, and then stated on the following lines before the function body, and variables in the body are still defined in it.
Discovering this made me recall an unrelated feature of old-style C function declarations: empty brackets do not mean no arguments but any number of any type. In C there is a dynamic language hiding, but it is so terrible and dangerous, we must never let it out. I discovered this in the Geant4 codebase, after I tried to figure out why some functions called without arguments actually had a void argument in their declaration (this blocks the above behaviour and enforces being called without arguments). In C++ this is unnecessary (because of function overloading empty brackets already have a specific meaning). I guess this must have carried over from peoples C training. I use
*args (although nowadays
**kwargs for obvious reasons) in Python, and it turns out C had a similar feature all along!