The Assembly Language of Object-Oriented Programming 207 Hard to Learn and Built to Stay That Way C++ shares one more important feature with assembly language—it is very difficult to learn and use, and even harder to learn to use well. Date: Mon, 8 Apr 91 11:29:56 PDT From: Daniel Weise daniel@mojave.stanford.edu To: UNIX-HATERS Subject: From their cradle to our grave. One reason why Unix programs are so fragile and unrobust is that C coders are trained from infancy to make them that way. For exam- ple, one of the first complete programs in Stroustrup’s C++ book (the one after the “hello world” program, which, by the way, compiles into a 300K image), is a program that performs inch-to-centimeter and centimeter-to-inch conversion. The user indicates the unit of the input by appending “i” for inches and “c” for centimeters. Here is the outline of the program, written in true Unix and C style: #include stream.h main() { [declarations] cin x ch A design abortion. This reads x, then reads ch. if (ch == 'i') [handle "i" case] else if (ch == 'c') [handle "c" case] else in = cm = 0 That’s right, don’t report an error. Just do something arbitrary. [perform conversion] } Thirteen pages later (page 31), an example is given that implements arrays with indexes that range from n to m, instead of the usual 0 to m. If the programmer gives an invalid index, the program just blithely returns the first element of the array. Unix brain death for- ever!
208 C++ Syntax Syrup of Ipecac Syntactic sugar causes cancer of the semi-colon. —Alan Perlis Practically every kind of syntax error you can make in the C programming language has been redefined in C++, so that now it produces compilable code. Unfortunately, these syntax errors don’t always produce valid code. The reason is that people aren’t perfect. They make typos. In C, no matter how bad it is, these typos are usually caught by the compiler. In C++ they slide right through, promising headaches when somebody actually tries to run the code. C++’s syntactical stew owes itself to the language’s heritage. C++ was never formally designed: it grew. As C++ evolved, a number of constructs were added that introduced ambiguities into the language. Ad hoc rules were used to disambiguate these. The result is a language with nonsensical rules that are so complicated they can rarely be learned. Instead, most pro- grammers keep them on a ready-reference card, or simply refuse to use all of C++’s features and merely program with a restricted subset. For example, there is a C++ rule that says any string that can be parsed as either a declaration or a statement is to be treated as a declaration. Parser experts cringe when they read things like that because they know that such rules are very difficult to implement correctly. AT&T didn’t even get some of these rules correct. For example, when Jim Roskind was trying to figure out the meanings of particular constructs—pieces of code that he thought reasonable humans might interpret differently—he wrote them up and fed them to AT&T’s “cfront” compiler. Cfront crashed. Indeed, if you pick up Jim Roskind’s free grammar for C++ from the Inter- net host ics.uci.edu, you will find the following note in the file c++grammar2.0.tar.Z in the directory ftp/pub: “It should be noted that my grammar cannot be in constant agreement with such implementa- tions as cfront because a) my grammar is internally consistent (mostly courtesy of its formal nature and yacc verification), and b) yacc gener- ated parsers don’t dump core. (I will probably take a lot of flack for that last snipe, but… every time I have had difficulty figuring what was meant syntactically by some construct that the ARM was vague about, and I fed it to cfront, cfront dumped core.)”
Previous Page Next Page