Saturday 12 November 2011

Program Flow Should Proceed “Straight Through”; gotos and Other Jumps Should Be Eliminated

Program Flow Should Proceed “Straight Through”; gotos and Other Jumps Should Be Eliminated

This principle, although generally accepted by the computer establishment, is still hotly debated in some
circles. However, it is generally agreed upon that programs with fewer statements that cause the program flow
to unconditionally skip parts of the code are much easier to debug. This is because such programs are generally more straightforward and easier to understand. What many programmers do not understand is how to replace these “unstructured jumps” (which they might have learned from programming in assembly language, FORTRAN, or BASIC) with the “correct” structured constructs. Here are a few examples of how
this task should be done:
for( a = 0 ; a < 100 ; ++ a )
{
Func1( a );
if ( a == 2 ) continue;
Func2( a );
}
This code uses the continue statement to skip the rest of the loop if a is equal to 2. This could be recoded
in the following manner
for( a = 0 ; a < 100 ; ++ a )
{
Func1( a );
if ( a != 2 )
Func2( a );
}
This code is easier to debug because you can tell what might be executed and what might not, based on the
braces. How does this make your code easier to modify and debug? Suppose that you wanted to add some
code that should be executed at the end of the loop every time. In the first case, if you noticed the continue,
you would have to make complex changes to the code (try this; it’s not intuitively obvious!). If you didn’t
notice the continue, you would get a hard-to-understand bug. For the second program fragment, the change
would be simple. You would simply add the new function to the end of the loop.
Another possible error can arise when you are using the break statement. Suppose that you had written the
following code:
for( a = 0 ; a < 100 ; ++ a )
{
if ( Func1( a ) == 2 )
break;
Func2( a );
}

This loop proceeds from one to 100—assuming that the return value of Func1() is never equal to 2. If this
situation ever occurs, the loop will terminate before reaching 100. If you are ever to add code to the loop, you might assume that it really does iterate from 0 to 99 based on the loop body. This assumption might cause you to make a dangerous error. Another danger could result from using the value of a; it’s not guaranteed to be 100 after the loop.

C enables you to account for this situation, by writing the for loop like this:
for( a = 0 ; a < 100 && Func1( a ) != 2 ; ++ a )
This loop explicitly states to the programmer, “Iterate from 0 to 99, but halt iteration if Func1() ever equals
2.” Because the entire exit condition is so apparent, it will be difficult to make a later mistake.

No comments:

Post a Comment