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.