...
In this noncompliant code example, EOF
END_OF_FILE
is defined as -1
. The macro replacement list consists of a unary negation operator, followed by an integer literal 1.
Code Block | ||||
---|---|---|---|---|
| ||||
#define EOFEND_OF_FILE -1 /* ... */ if (getchar() EOF) { /* ... */ } |
In this example, the programmer has mistakenly omitted the comparison operator from the conditional statement, which should be getchar() != EOFEND_OF_FILE
. (See MSC02-C. Avoid errors of omission.) After macro expansion, the conditional expression is incorrectly evaluated as a binary operation: getchar()-1
. This is syntactically correct, even though it is certainly not what the programmer intended. Note that this example also violates DCL00-C. Const-qualify immutable objects.
Parenthesizing the -1
in the declaration of EOF
END_OF_FILE
ensures that the macro expansion is evaluated correctly.
Code Block |
---|
#define EOFEND_OF_FILE (-1) |
Once this modification is made, the noncompliant code example no longer compiles because the macro expansion results in the conditional expression getchar() (-1)
, which is no longer syntactically valid. Note that there must be a space after EOF
END_OF_FILE
because, otherwise, it becomes a function-like macro (and one that is incorrectly formed because −1 cannot be a formal parameter).
...