C Language

One Last Comment

Most programmers know that "comments lie," which is why high-level languages should let you directly express what your program does rather than force you to comment unclear code. C programmers will find that comments can also make their code lie! Read the fragment in Figure 3.2 carefully. A comment warns anybody reading the code about an important condition that changes at this point in the program flow. The comment tells us that here is where the variable prv_opcode changes from the previous opcode to the current opcode. A look at the C code seems to verify that the comment doesn't lie. But the C code (or what looks like C code) itself lies. The statement

 strcpy(prv_opcode, op_code);

doesn't copy op_code to prv_opcode. It doesn't do anything - it's part of a multiline comment, not executable code. The comment ends with the */ on the last line in the figure, making all of Figure 3.2 one long comment.

Figure 3.2 - Sample C Code

/* IMPORTANT NOTE: prv_opcode is set here, after handling vendor-specific translations and blank opcodes. After this section, opcode may be modified. You should _not_ test prv_opcode after this point because it now holds the current opcode.
 strcpy(prv_opcode, opcode);
 op_is_ctlop = FALSE;
 /* Control opcodes are ones that cause indentation:
   BEGSR, IFxx, DO, DOUxx, and DOWxx.*/

[Note call-outs - see magazine version, p. 114, Sept. 91]

C uses /* and */ to delimit comments. C also implicitly continues open comments across multiple lines until the ending */ is encountered. This makes it easy to have "runaway" comments that encompass what's intended as executable code. Unintentionally commented-out code, especially if it's initialization code, can cause mysterious program behavior. You see the program fail, you look at the code, and it "can't do that!" Only when, on your tenth look, you finally catch that the comment a page up has no closing */ do you unfold the mystery.

No foolproof way exists to avoid runaway C comments. (Newer languages such as Ada let you prevent this problem by using - to start comments that end at the end of the line.) Two rules can help: Place the opening /* and closing */ for comments on lines by themselves, and use a vertical bar to begin each line of comment text. For example,

 |Comment lines
 |are here

This practice avoids the most common cause of a missing */ - editing the last line of a comment and accidentally deleting the */ at the end of the line. It's also easier to check visually for matching comment delimiters when they appear at the same indentation level in the source. In addition, some C "lint" utilities can catch occurrences of /* inside a comment, which usually indicates a missing */.