COBOL Segments

Don't use segmentation unless you have to. If you do have to, make sure you know what you're doing, and how to avoid the dangers.

Why You Might Have to

In the bad old days, when computers were physically huge and logically tiny, segmentation was a useful technique for making large programs fit into the machine. The idea was to avoid loading the entire program at once. Divide the program up into segments, and swap them in and out of memory as needed.

For example, many programs have some initialization code, a main loop, and some finishing-up code. Once the initialization code has run, you don't need to keep it around any more. Overlay it with the main loop. When the main loop is finished, throw it away and load the finishing-up code.

These days, most big machines use virtual memory to serve the same purpose. However, if you inherit a fossilized program from the 60's with segmentation still intact, you'll need to understand how it works. Or, if you port a big program to an MS-DOS machine with 640K of memory, you might have to use segmentation to make it work at all.

Segmentation Syntax

A section header may carry a one- or two-digit segment number between "SECTION" and the terminating period (IBM literature often refers to a segment number as a "priority"):
 1000-BEGIN-JOB SECTION 20.
All sections with the same segment number comprise a segment. In some dialects, all sections of a given segment must be contiguous.

Types of Segments

Segments numbered from 0 through 49 are "fixed" segments; those numbered from 50 through 99 are "independent" segments.

Fixed segments may be further subdivided into "overlayable" and "non-overlayable" segments, according to the SEGMENT-LIMIT specified in the OBJECT-COMPUTER paragraph of the CONFIGURATION SECTION. However, I will ignore this distinction, which may affect performance but not program behavior.

The main difference between fixed segments and independent segments is that the code in fixed segments behaves normally, and the code in independent segments may not.

Sick Segments

A segment contains not only executable code but also some unnamed data fields which govern the flow of control. At runtime, these fields keep track of which PERFORMs are active at a given time, how the PERFORMs are nested, and what are the destinations of active THRU clauses. They also record the current destination of altered GO TOs.

When you overlay a fixed segment, the associated control fields are preserved intact. If you restore the same segment later, the control fields are still available in their last-used state.

Not so with an independent segment. When you overlay it, you overlay not only the executable code but also the associated control fields. When you reload it, you reload the control fields in their initial state. No paragraph in the independent segment can remember who was in control when the segment was overlaid earlier. If there is an altered GO TO in the segment, it is restored to its original destination.

As a result, careless segmentation can lead to bizarre and unexpected behavior. For example:

 2250-ISRT-MSG SECTION 55.
*
     CALL 'CBLTDL' USING ISRT
                         JK-PCB
                         JK-MSG.
*
     IF JK-PCB-STATUS NOT = SPACES
        PERFORM 9820-REPORT-PCB-ERROR.
...
 9820-REPORT-PCB-ERROR SECTION 65.
*
     CALL 'JKIMSERR' USING JK-PCB-STATUS
                           MSG-178-MSG.
     DISPLAY MSG-178-BAD-PCB-ISRT.
     SET FATAL-ERROR-FOUND TO TRUE.
These sections are in two different independent segments. When 2250-ISRT-MSG invokes 9820-REPORT-PCB-ERROR, the run-time system loads segment 65, overlaying segment 55. When 9820-REPORT-PCB-ERROR has finished, it returns control to 2250-ISRT-MSG, causing segment 55 to be reloaded.

By this point, however, segment 55 retains no information about which paragraph originally PERFORMed 2250-ISRT-MSG, if any. When execution reaches the end of the paragraph, it falls through into the next one, and then the next, and so forth.

The only thing uglier than an accident like this is a program that works this way on purpose.

Moral: if you use segmentation, make sure that no independent segment invokes any code in any other independent segment, directly or indirectly.

Acknowledgements

I've never had the misfortune to encounter segmentation myself. The above description is based on a discussion among the denizens of comp.lang.cobol, to whom I am grateful. I am particularly grateful to Tom Morrison of Liant Software (home of the Ryan-McFarland compiler), who provided a detailed description of segmentation.
[home]Cobol Home [style forum]Cobol Style Forum