Conversations I have had with technical staff of several large microcomputer software companies illustrate what, I think, is the prevalent viewpoint in the C programming culture. I asked experienced C programmers whether they regularly encountered the kinds of problems I've described so far, and they all said, in effect, "Of course, it's just part of programming in C." Then I asked them how they handled a couple of the most common problems, and with one exception, they said they relied on "careful programming," lint filters, and good debuggers. The one exception said he built his own layer of abstract data types to insulate himself from C. (In following chapters, I offer techniques along these lines.)
The most insightful reflection about C I've heard is from the computer scientist Bertrand Meyer, who designed the Eiffel programming language. He said, "How could I even try to teach systematic algorithm construction when I knew the bulk of the C students' time was spent fighting tricky pointer arithmetic, chasing memory allocation bugs, trying to figure out whether an argument was a value or a pointer, making sure the number of asterisks was right, and so on. I'm afraid it will be hard to recover from the damage caused by C to an entire generation of programmers."
The same assessment was put more briefly by the programmer who said, "C's a double-edged sword-without any handle."
C can do you harm, and not just if you're inexperienced. I will try to give you a handle on C so you can wield it as safely as possible. In future chapters, I will describe other ways that C can trip you up and suggest programming practices to avoid common problems. If you're considering C, either for workstation or AS/400 development, you'll gain a better understanding of some of the risks you face. If you're already using C, these tips will help you minimize your risks.
* * * * *
To experienced C programmers only: Did you catch the other errors I made in coding Figure 2.1? I'll point them out in Chapter 3.
Sidebar 1 - C Coding Suggestions
- * Don't use = in an if statement expression, unless it is absolutely necessary.
- * Define a macro EQ for ==, and never use ==.
- * Define macros for &, |, &&, and ||.
- * Define macros for BOOL, TRUE, and FALSE.
- * Use only Boolean-valued expressions in if statements.
- * Use only Boolean variables with the logical operators && and ||.
- * Do all assignments as separate statements, not as part of a more complex expression.
- * Use parentheses in expressions to explicitly define order of evaluation.
- * Don't use %i format specifications or numbers that begin with 0.
- * Be sure to code addresses for arguments to scanf and similar functions.