There should be no more than one statement per line of source text. The preferred place to break up expressions that won't fit on a single line is before the lowest-precedence operator in the expression.
The conditional operator "... ? ... : ..."
should be avoided,
unless it results in
substantially more readable code than the equivalent if-else
.
The comma operator should not be used to substitute for a block of statements. The only recommended use of a comma operator is in the initialization or increment clauses of a for loop.
Example:
/* reverse the order of chars in s */ for (i = 0, j = strlen(s) - 1; i < j; ++i, --j) { char tmp; tmp = s[i]; s[i] = s[j]; s[j] = tmp; }
Side effects which rely on the evaluation order of "&&"
or
"||"
should be avoided.
Example:
/* bad */ if (i_filename != NULL && (i_fd = uropen(i_filename)) == ERROR) { error("can't open %s", i_filename); } /* good */ if (i_filename != NULL) { i_fd = uropen(i_filename); if (i_fd == ERROR) { error("can't open %s", i_filename); } }
In this example, the recommended form emphasizes that:
i_fd
is set only when i_filename
is
non-NULL
.
uropen
, but only an indirect consequence of whether
i_filename
is NULL
.
Expressions with side effects should NEVER appear in a function argument list.
Logical expressions are usually clearer if they are reformulated to eliminate a
leading "!"
.
Example:
/* bad */ if (!(i < 0 || i >= n) ) { ... } /* good */ if (i >= 0 && i < n) { ... } /* acceptable */ if (! isascii(c)) { ... }
Embedded assignment expressions should be avoided, except where necessary for loop control, in which case it is ESSENTIAL that the assignment expression be fully parenthesized and explicitly tested.
Example:
/* BAD */ /* good */ while (c = nextc()) { while ((c = nextc() ) != EOS) { ... ... } }
Confusion about operator precedence in C is a rich source of bugs. In general, expressions should be fully parenthesized if they contain:
"||"
and "&&"
Use of white space should not suggest a misleading operator precedence.
Example:
a+b * c