Changing Fall-Throughs into GO TOs

At the end of a COBOL paragraph, any of several things may happen:
  1. Control always returns to the PERFORMing paragraph.
  2. Control always goes somewhere else via a GO TO (or perhaps via a GOBACK or the like).
  3. Control always falls through into the next paragraph.
  4. Control is ambiguous: sometimes it returns and sometimes it falls through.
Your goal at this point is to identify all instances of the third and fourth categories, and transform them into the second category.

A Simple Example

Consider the following code fragment:
     3510-VALIDATE-ACTION-CODE.
*    do some stuff; no GO TOs

     3520-VALIDATE-USOC.
*    do some more stuff
Assume that 3510-VALIDATE-ACTION-CODE receives control only by a GO TO. Since it contains no GO TOs itself, control always falls into 3520-VALIDATE-USOC. Add a GO TO at the end of 3510-VALIDATE-ACTION-CODE:
     3510-VALIDATE-ACTION-CODE.
*    do some stuff; no GO TOs
     GO TO 3520-VALIDATE-USOC.

     3520-VALIDATE-USOC.
*    do some more stuff
Given the assumptions, this addition is safe because it does not change the existing flow of control.

Yes, Really

Adding a GO TO may seem like a step backwards. You're trying to eliminate GO TOs, not create more of them.

In this case the addition is benign. In effect, the GO TO was already there -- you're just making it visible.

More importantly, the explicit GO TO enables you to add a new paragraph in the middle without interrupting the flow of control. Once you have eliminated all fall-through logic, you can move paragraphs around at will.

A Slightly Less Simple Example

Consider a variation of the above example, using the same assumptions:
     3510-VALIDATE-ACTION-CODE.
*    do some stuff
     IF CODE-NOT-VALID
        GO TO 3595-ISSUE-ERROR-MESSAGE.
*    do some stuff; no more GO TOs

     3520-VALIDATE-USOC.
*    do some more stuff
Because of the GO TO, control sometimes falls through into 3520-VALIDATE-USOC, and sometimes doesn't. However, you can treat this example the same as you treated the first one, by adding a GO TO 3520-VALIDATE-USOC at the end.

At this point you are only concerned with what happens when control actually reaches the bottom of the paragraph. If it doesn't get there because of a GO TO, that fact doesn't alter your course of action.

Ambiguous Fall-Throughs

Return to the first example:
     3510-VALIDATE-ACTION-CODE.
*    do some stuff; no GO TOs

     3520-VALIDATE-USOC.
*    do some more stuff
This time, however, let's change our assumptions. Assume that control enters the first paragraph by two different routes:
  1. By a simple PERFORM or PERFORM UNTIL (with no THRU clause);
  2. By a GO TO, a PERFORM THRU, or a fall-through from the previous paragraph.
If you add a GO TO at the end as described above, you would disrupt the flow of control when the paragraph is PERFORMed. The solution is to change the code which invokes 3510-VALIDATE-ACTION-CODE.

Where the code reads:

     GO TO 3510-VALIDATE-ACTION-CODE.
...change it to:
     PERFORM 3510-VALIDATE-ACTION-CODE.
     GO TO 3520-VALIDATE-USOC.
This change is safe because it does not change the flow of control. In fact this change anticipates a later stage of transformation, in which you will let GO TOs percolate upwards.

Where the code reads:

     PERFORM 3510-VALIDATE-ACTION-CODE THROUGH 3599-EXIT.
...change it to:
     PERFORM 3510-VALIDATE-ACTION-CODE.
     PERFORM 3520-VALIDATE-USOC THRU 3599-EXIT.
If the paragraph receives control by a fall-through from the previous paragraph, then you're not ready to fix this paragraph yet. Fix the previous one first.

Start at the Top

Even in the absence of GO TO or PERFORM THRU, fall-through logic begins as soon as the program receives control -- either at an ENTRY statement or at the first statement in the PROCEDURE DIVISION (after any declaratives).

Ideally, the paragraph which first receives control should end with STOP RUN, GOBACK, or a similar construct. If so, fall-through logic can arise only with GO TO or PERFORM THRU statements, which you can find quickly in the editor. Otherwise, control is likely to fall into the next paragraph, and the next.

Either way, you must identify all the places where fall-through logic occurs.

If control falls into one paragraph, it presumably falls into the next as well, unless you can prove otherwise. Because of the way paragraphs can inherit control from preceding paragraphs, you must work downwards from each point where fall-through logic begins. Wherever you find fall-through logic, use the methods described above to eliminate it.

Mark What You Can't Eliminate

You can usually eliminate most of the fall-through logic without much difficulty. Some of the logic, however, may resist such a simplistic (though tedious) approach. If so, don't worry about if for now. Just mark the offending gaps between paragraphs with big prominent comments so that you will not disrupt them by accident.

The code will become easier to manage as you continue through later stages of the rewrite. Eventually you can find a way to unravel even the worst tangles.


[style forum]COBOL Style Forum [spaghetti]Spaghetti code [stage]Next stage
[home]COBOL Home