Control structures
General rules
- Control structure keywords MUST be followed by a whitespace.
This is correct:
|
- The conditional parts of algorithmic constructs (
if, while,
do, for), and the else keyword,
MUST be alone on their line.
These constructs are incorrect:
|
while (*s) write(1, s++, 1);
if (x == 3) {
foo3();
bar();
} else {
foo();
baz();
}
do {
++x;
} while (x < 10);
|
|
These are correct:
|
while (*s)
write(1, s++, 1);
if (x == 3)
{
foo3();
bar();
}
else
{
foo();
baz();
}
do
{
++x;
}
while (x < 10);
|
|
while and do ... while
- The
do ... while construct MAY be used, but appropriate
use of the while and for constructs is preferred.
for
Exceptions to other specifications (See Statements,
see Structures variables and declarations) can be found in this section.
- Multiple statements MAY appear in the initial and iteration part
of the
for structure.
- For this effect, commas MAY be used to separate statements.
- Variables MUST NOT be declared in the initial part of the
for construct.
This is wrong:
|
for (int i = 0, j = 1;
p = i + j, p < 10;
++i, ++j)
{
/* ... */
}
|
|
This is correct:
|
int i;
for (i = 0, j = 1, p = i + j;
p < 10;
++i, ++j, p = i + j)
{
/* ... */
}
|
|
- As shown in the previous examples, the three parts of the
for
construct MAY span over multiple lines.
- Each of the three parts of the
for construct MAY be
empty. Note that more often than not, the while construct
better represents the loop resulting from a for with an
empty initial part.
This is correct:
|
Loops, general rules
The switch construct
- The
switch MUST be used only over enumeration types.
- Incomplete
switch constructs (that is, which do not cover all
cases of an enumeration),
MUST contain a default case.
- Non-empty
switch condition blocks SHALL NOT crossover. That is,
all non-empty case blocks MUST end with a break,
including the default block. This restriction is
tampered by some particular uses of return, as described
below.
- Control structure MUST NOT span over several
case blocks.
This is very wrong:
|
switch (c)
{
case c_x:
while (something)
{
foo();
case c_y:
bar();
}
}
|
|
- Each
case conditional MUST be indented from the associated
switch once, and the code associated with the case conditional
MUST be indented from the case.
This is wrong:
|
switch (c)
{
case c_x: foo(); break;
case c_y:
bar();
break;
default:
break;
}
|
|
| This is correct:
|
switch (c)
{
case c_x:
foo();
break;
case c_y:
bar();
break;
default:
break;
}
|
|
This is also correct:
|
switch (c)
{
case c_x:
foo();
break;
case c_y:
bar();
break;
default:
break;
}
|
|
- When a
case block contains a return statement
at the same level than the final break, then all case blocks
in the same switch (including default) SHOULD end with
return, too. In this particular case, the return
statement MAY replace the break statement.
This is inelegant:
|
switch (direction)
{
case d_left:
return go_to_left();
break;
case d_right:
return go_to_right();
case d_down:
printf("Wrong\n");
break;
default:
break;
}
return do_it();
|
|
This is elegant:
|
switch (direction)
{
case d_left:
return go_to_left();
case d_right:
return go_to_right();
case d_down:
printf("Wrong\n");
return do_it();
case d_up:
return do_it();
}
|
|
Rationale: when using switch to choose between different return values,
no condition branch should allowed to "fall off" without a value.
- There MUST NOT be any whitespace between a label and the following
colon (":"), or between the
default keyword and the
following colon.