TITLE: **p++^=q++=*r---s AUTHOR: Eugene Wallingford DATE: February 23, 2007 7:58 PM DESC: ----- BODY: I thought about calling this piece "The Case Against C" but figured that this legal expression in the language makes a reasonably good case on its own. Besides, that is the name of a old paper by P.J. Moylan from which I grabbed the expression. ( PDF | HTML, minus footers with quotes) When I first ran across a reference to this paper, I thought it might make a good post for my attempt at the Week of Science, but by the author's own admission this is more diatribe than science.

C is a medium-level language combining
the power of assembly language with
the readability of assembly language.

I finally finished reading the paper on my way home from ChiliPLoP, and it presented a well-reasoned argument that computer scientists and programmers consider using languages that incorporate advances in programming languages since the creation of C. He doesn't diss C, and even professes an admiration for it; rather he speaks to specific features about which we know much more now than we did in the early 1970s. I ended up collecting a few good quotes, like the one above, and a few good facts, trivia, and guidelines. I'll share some of the more notable with you. Facts, Trivia, and Guidelines

  • One of the features of C that is behind the times is its weak support for modular code. C supports separate compilation of modules, but Moylan reminds us that modularity is really about information hiding and abstraction. In this regard, C's system is lacking. Moylan gives a very nice description of ten practices that one can adopt in order to build effective modular programs in C, ranging from technical advice such as "Exactly one header file per module.", "Every module must import its own header file, as a consistency check.", and "The compiler warning 'function call without prototype" should be enabled, and any warning should be treated as an error." to team practices such as "Ideally, programmers working in a team should not have access to one another's source files. They should share only object modules and header files." He is not optimistic about the consistent use of these rules, though:
    Now, the obvious difficulty with these rules is that few people will stick to them, because the compiler does not enforce them. ... And, what is worse, it takes only one programmer in a team to break the modularity of a project, and to force the rest of the team to waste time with grep and with mysterious errors caused by unexpected side-effects.
  • Moylan gives a simple example that as concisely as possible how C's #include directive can lead to a program that is in an inconsistent state because some modules which should have been re-compiled were not. The remedy of always recompiling everything is obviously unattractive to anyone working on a large system.
  • Conventional wisdom says that C compilers produce faster code than compilers for other things. Moylan objects on several grounds, including the lack of any substantial recent evidence for the conventional wisdom. He closes with my favorite piece of trivia from the paper:
    It is true that C compilers produced better code, in many cases, than the Fortran compilers of the early 1970s. This was because of the very close relationship between the C language and PDP-11 assembly language. (Constructs like *p++ in C have the same justification as the three-way IF of Fortran II: they exploit a special feature of the instruction set architecture of one particular processor.) If your processor is not a PDP-11, this advantage is lost.
    I learned my assembly language and JCL on an IBM mainframe and so never had the pleasure of writing assembly for a PDP-11. (I did learn Lisp on a PDP-8, though...) Now I want to go learn about the PDP-11's assembly language so that I can use this example at greater depth in my compilers course next semester. Favorite Quotes You've already seen one above. My other favorite is:
    Much of the power of C comes from having a powerful preprocessor. The preprocessor is called a programmer.
    There were other good ones, but they lack the technical cleanness of the best because they could well be said of other languages. Examples from this category include "By analysis of usenet source, the hardest part of C to use is the comment." and "Real programmers can write C in any language." (My younger readers may not know what Moylan means by "usenet", which makes me feel old. But they can learn more about it here.) ---- As readers here probably know from earlier posts such as this one, I'm as tempted by a guilty language pleasure as anyone, so I enjoyed Moylan's article. But even if we discount the paper's value for its unabashed advocacy on language matters, we can also learn from his motivation:
    I am not so naive as to expect that diatribes such as this will cause the language to die out. Loyalty to a language is very largely an emotional issue which is not subject to rational debate. I would hope, however, that I can convince at least some people to re-think their positions.

    I recognise, too, that factors other than the inherent quality of a language can be important. Compiler availability is one such factor. Re-use of existing software is another; it can dictate the continued use of a language even when it is clearly not the best choice on other grounds. (Indeed, I continue to use the language myself for some projects, mainly for this reason.) What we need to guard against, however, is making inappropriate choices through simple inertia.

    Just to keep in mind that we have a choice of language each time we start a new project is a worthwhile lesson to learn. -----