# 14. Flow Control Structures

Rule 47
The code following a `case` label must always be terminated by a `break` statement.
Rule 48
A `switch` statement must always contain a `default` branch which handles unexpected cases.
Rule 49
Never use `goto`.
Rec. 50
The choice of loop construct (`for`, `while` or `do-while`) should depend on the specific use of the loop.
Rec. 51
Always use `unsigned` for variables which cannot reasonably have negative values.
Rec. 52
Always use inclusive lower limits and exclusive upper limits.
Rec. 53
Avoid the use of `continue`.
Rec. 54
Use `break` to exit a loop if this avoids the use of flags.
Rec. 55
Do not write logical expressions of the type `if(test)` or `if(!test)` when `test` is a pointer.

Each loop construct has a specific usage. A `for` loop is used only when the loop variable is increased by a constant amount for each iteration and when the termination of the loop is determined by a constant expression. In other cases, `while` or `do-while` should be used. When the terminating condition can be evaluated at the beginning of the loop, `while` should be used; `do-while` is used when the terminating condition is best evaluated at the end of the loop.

`Goto` breaks the control flow and can lead to code that is difficult to comprehend. In addition, there are limitations for when `goto` can be used. For example, it is not permitted to jump past a statement that initializes a local object having a destructor.

Variables representing size or length are typical candidates for `unsigned` declarations. By following this recommendation some unpleasant errors can be avoided.

It is best to use inclusive lower and exclusive upper limits. Instead of saying that `x` is in the interval `x>=23` and `x<=42`, use the limits `x>=23` and `x<43`. The following important claims then apply:

• The size of the interval between the limits is the difference between the limits.
• The limits are equal if the interval is empty.
• The upper limit is never less than the lower limit.

By being consistent in this regard, many difficult errors will be avoided.

If the code which follows a `case` label is not terminated by `break,` the execution continues after the next `case` label. This means that poorly tested code can be erroneous and still seem to work.

`continue` can be used to exit from loops. However, code may be more comprehensible by using an `else` clause instead.

C++ has a very loose and, simultaneously, very free way of determining if an expression is true or false. If an expression is evaluated as 0, it is false; otherwise, it is considered to be true.

We do not recommend logical tests such as "`if(`pointer`)`" if "pointer" is a variable of pointer-type. The only reason is readablity; many programmers find it difficult to read such code.

Consider the scope within which an iteration variable is visible. A variable that is declared within a ``for`' statement is currently only visible in the nearest enclosing block. The standardization committee for C++ is however discussing a language modification regarding this point. No decision has yet been made. Still, this problem is avoided if the control structure is encapsulated in a compound statement.

Exception to Rule 47
When several `case` labels are followed by the same block of code, only one `break` statement is needed. Also, other statements than `break` may be used to exit a `switch` statement, such as `return`.
Exception to Rule 48
No exceptions.
Exception to Rule 49
For extremely time-critical applications or for fault handling, `goto` may be permitted. Every such usage must be carefully motivated.

### Example 56: Problem using unsigned loop variables

```   for( unsigned int i = 3; i >= 0; --i )
{
// This loop will never terminate, since i cycles through:
// 3, 2, 1, 0, 4294967295, 4294967294, etc ... on a SparcStation
// Note that this example does not follow the rules: i >= 0
// in the for statement. See next example !
}
```

### Example 57: Visibility of variable declared in ``for`' loop

```   for ( int index = 0; index < 10; index++ )
{
cout << index;
}

int index = 3;   // ERROR, THIS IS AN ILLEGAL RE-DECLARATION OF index
// BECAUSE index IS DECLARED IN BLOCK-SCOPE.
```

### Example 58: Dangerous `switch`/`case` statement

```   switch ( tag )
{
case A:
{
// Do something
// Next statement is a call to foo() inside next case
}

case B:
{
foo();
// Do something else
break;      // Now we leave the switch-statement
}

default:
{
// If no match in above cases, this is executed
exit( 1 );
}
}
```

### Example 59: Good and bad ways of setting limits for loop variables

```   int a[10];
int ten = 10;
int nine = 9;

// Good way to do it:
for( int i = 0; i < ten; i++ )       // Loop runs 10-0=10 times
{
a[i] = 0;
}

// Bad way to do it:
for( int j = 0; j <= nine; j++ )     // Loop runs 10 times, but 9-0=9 !!!
{
a[j] = 0;
}
```

### Example 60: Using break to exit a loop, no flags are needed.

```   do                                   // This way:
{
if ( Something )
{
// Do something
break;
}
} while( someCondition );

int endFlag = 0;                     // Is better than this:
do
{
if ( /* Something */ )
{
// Do something
endFlag = 1;
}
} while( someCondition && !endFlag );
```

### Example 61: By using an extra ``else`' clause, `continue` is avoided and the code can be comprehended.

```   while( /* Something */ )             // This way is more clear
{
if( /* Something */ )
{
// Do something
}
else
{
// Do something else
}
}

while( /* Something */ )             // Than using continue
{
if( /* Something */ )
{
// Do something
continue;                     // No !
}
// Do something else
}
```