MainframeMaster

COBOL Tutorial

COBOL END-PERFORM Statement

The END-PERFORM statement represents a fundamental component of structured programming in COBOL, serving as an explicit scope terminator that clearly defines the boundaries of PERFORM statement blocks. This statement embodies modern programming principles by providing unambiguous termination points for iterative operations, enabling sophisticated loop control mechanisms, and supporting the development of robust, maintainable applications that leverage structured programming paradigms for code clarity and logical flow control.

In contemporary enterprise COBOL development, END-PERFORM plays a vital role in creating sophisticated control structures that must handle complex iteration scenarios, nested loop operations, and conditional processing logic. By providing explicit termination for PERFORM blocks, this statement enables developers to implement comprehensive loop control logic while maintaining code readability and ensuring that iterative operations are properly bounded and controlled within the application's execution flow.

Understanding END-PERFORM Architecture

The END-PERFORM statement implements sophisticated scope management for iterative operations. This architecture addresses the complexity inherent in modern programming scenarios where PERFORM statements must manage loop variables, conditional termination, nested iterations, and complex control flow logic. The explicit termination provided by END-PERFORM ensures that all these operations are properly contained within defined boundaries.

The architectural design of END-PERFORM reflects the evolution of COBOL toward structured programming paradigms that emphasize clear control flow, proper scope management, and maintainable code organization. When used with various PERFORM variants including UNTIL, TIMES, and VARYING clauses, END-PERFORM creates a comprehensive framework for handling complex iteration patterns and loop control scenarios.

END-PERFORM also plays a crucial role in compiler optimization and runtime performance. Modern COBOL compilers can perform more sophisticated analysis when loop boundaries are explicitly defined, leading to better loop optimization, more efficient code generation, and improved runtime performance for iterative operations.

Basic END-PERFORM Usage

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
IDENTIFICATION DIVISION. PROGRAM-ID. END-PERFORM-DEMO. DATA DIVISION. WORKING-STORAGE SECTION. 01 LOOP-CONTROLS. 05 COUNTER PIC 9(3) VALUE 0. 05 MAX-ITERATIONS PIC 9(3) VALUE 10. 05 TOTAL-SUM PIC 9(5) VALUE 0. 05 ARRAY-INDEX PIC 9(2) VALUE 1. 01 NUMBER-ARRAY. 05 NUMBERS OCCURS 10 TIMES PIC 9(3). 01 PROCESSING-FLAGS. 05 CONTINUE-FLAG PIC X VALUE 'Y'. 88 CONTINUE-PROCESSING VALUE 'Y'. 88 STOP-PROCESSING VALUE 'N'. 05 FOUND-FLAG PIC X VALUE 'N'. 88 ITEM-FOUND VALUE 'Y'. 88 ITEM-NOT-FOUND VALUE 'N'. PROCEDURE DIVISION. MAIN-PROCESSING. PERFORM INITIALIZE-DATA PERFORM DEMONSTRATE-BASIC-LOOPS PERFORM DEMONSTRATE-CONDITIONAL-LOOPS PERFORM DEMONSTRATE-NESTED-LOOPS PERFORM DEMONSTRATE-VARYING-LOOPS STOP RUN. INITIALIZE-DATA. *> Initialize array with sample data PERFORM VARYING ARRAY-INDEX FROM 1 BY 1 UNTIL ARRAY-INDEX > 10 COMPUTE NUMBERS(ARRAY-INDEX) = ARRAY-INDEX * 5 DISPLAY 'Initialized NUMBERS(' ARRAY-INDEX ') = ' NUMBERS(ARRAY-INDEX) END-PERFORM MOVE 0 TO TOTAL-SUM MOVE 0 TO COUNTER DISPLAY 'Data initialization completed'. DEMONSTRATE-BASIC-LOOPS. DISPLAY 'Demonstrating basic PERFORM loops:' *> Simple PERFORM TIMES loop PERFORM 5 TIMES ADD 1 TO COUNTER DISPLAY 'Basic loop iteration: ' COUNTER END-PERFORM DISPLAY 'Basic loop completed. Final counter: ' COUNTER MOVE 0 TO COUNTER. DEMONSTRATE-CONDITIONAL-LOOPS. DISPLAY 'Demonstrating conditional PERFORM loops:' *> PERFORM UNTIL loop with condition PERFORM UNTIL COUNTER >= MAX-ITERATIONS ADD 1 TO COUNTER COMPUTE TOTAL-SUM = TOTAL-SUM + COUNTER DISPLAY 'Counter: ' COUNTER ' Running sum: ' TOTAL-SUM *> Conditional processing within loop IF COUNTER = 5 DISPLAY 'Reached midpoint of processing' END-IF IF COUNTER = 8 DISPLAY 'Approaching end of processing' END-IF END-PERFORM DISPLAY 'Conditional loop completed' DISPLAY 'Final counter: ' COUNTER DISPLAY 'Total sum: ' TOTAL-SUM. DEMONSTRATE-NESTED-LOOPS. DISPLAY 'Demonstrating nested PERFORM loops:' MOVE 0 TO COUNTER *> Outer loop PERFORM VARYING COUNTER FROM 1 BY 1 UNTIL COUNTER > 3 DISPLAY 'Outer loop iteration: ' COUNTER *> Inner loop PERFORM VARYING ARRAY-INDEX FROM 1 BY 1 UNTIL ARRAY-INDEX > 4 DISPLAY ' Inner loop iteration: ' ARRAY-INDEX DISPLAY ' Product: ' COUNTER * ARRAY-INDEX END-PERFORM DISPLAY 'Completed inner loop for outer iteration: ' COUNTER END-PERFORM DISPLAY 'Nested loops completed'. DEMONSTRATE-VARYING-LOOPS. DISPLAY 'Demonstrating PERFORM VARYING loops:' *> Process array elements MOVE 0 TO TOTAL-SUM PERFORM VARYING ARRAY-INDEX FROM 1 BY 1 UNTIL ARRAY-INDEX > 10 ADD NUMBERS(ARRAY-INDEX) TO TOTAL-SUM DISPLAY 'Processing element ' ARRAY-INDEX ': ' NUMBERS(ARRAY-INDEX) DISPLAY 'Running total: ' TOTAL-SUM END-PERFORM DISPLAY 'Array processing completed' DISPLAY 'Final total: ' TOTAL-SUM *> Search for specific value MOVE 25 TO COUNTER *> Search for value 25 SET ITEM-NOT-FOUND TO TRUE PERFORM VARYING ARRAY-INDEX FROM 1 BY 1 UNTIL ARRAY-INDEX > 10 OR ITEM-FOUND IF NUMBERS(ARRAY-INDEX) = COUNTER SET ITEM-FOUND TO TRUE DISPLAY 'Found value ' COUNTER ' at position ' ARRAY-INDEX END-IF END-PERFORM IF ITEM-NOT-FOUND DISPLAY 'Value ' COUNTER ' not found in array' END-IF.

Advanced END-PERFORM Patterns

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
IDENTIFICATION DIVISION. PROGRAM-ID. ADVANCED-END-PERFORM. DATA DIVISION. WORKING-STORAGE SECTION. 01 MATRIX-PROCESSING. 05 MATRIX-SIZE PIC 9(2) VALUE 5. 05 ROW-INDEX PIC 9(2). 05 COL-INDEX PIC 9(2). 05 MATRIX-ELEMENT PIC 9(3). 05 MATRIX-SUM PIC 9(7) VALUE 0. 01 DATA-MATRIX. 05 MATRIX-ROWS OCCURS 5 TIMES. 10 MATRIX-COLS OCCURS 5 TIMES PIC 9(3). 01 BATCH-PROCESSING. 05 BATCH-SIZE PIC 9(4) VALUE 1000. 05 CURRENT-BATCH PIC 9(4) VALUE 0. 05 RECORDS-PROCESSED PIC 9(7) VALUE 0. 05 SUCCESSFUL-RECORDS PIC 9(7) VALUE 0. 05 FAILED-RECORDS PIC 9(7) VALUE 0. 01 ERROR-HANDLING. 05 ERROR-COUNT PIC 9(3) VALUE 0. 05 MAX-ERRORS PIC 9(3) VALUE 10. 05 RETRY-COUNT PIC 9(2) VALUE 0. 05 MAX-RETRIES PIC 9(2) VALUE 3. 01 COMPLEX-CONDITIONS. 05 PROCESSING-COMPLETE PIC X VALUE 'N'. 88 PROCESSING-DONE VALUE 'Y'. 88 PROCESSING-ACTIVE VALUE 'N'. 05 ERROR-THRESHOLD-REACHED PIC X VALUE 'N'. 88 TOO-MANY-ERRORS VALUE 'Y'. 88 ERRORS-ACCEPTABLE VALUE 'N'. PROCEDURE DIVISION. MAIN-PROCESSING. PERFORM INITIALIZE-MATRIX PERFORM PROCESS-MATRIX-OPERATIONS PERFORM DEMONSTRATE-BATCH-PROCESSING PERFORM DEMONSTRATE-ERROR-HANDLING PERFORM DEMONSTRATE-COMPLEX-CONDITIONS STOP RUN. INITIALIZE-MATRIX. DISPLAY 'Initializing matrix with calculated values:' *> Initialize matrix with calculated values PERFORM VARYING ROW-INDEX FROM 1 BY 1 UNTIL ROW-INDEX > MATRIX-SIZE PERFORM VARYING COL-INDEX FROM 1 BY 1 UNTIL COL-INDEX > MATRIX-SIZE COMPUTE MATRIX-ELEMENT = (ROW-INDEX * 10) + COL-INDEX MOVE MATRIX-ELEMENT TO MATRIX-COLS(ROW-INDEX, COL-INDEX) DISPLAY 'Matrix[' ROW-INDEX ',' COL-INDEX '] = ' MATRIX-ELEMENT END-PERFORM END-PERFORM DISPLAY 'Matrix initialization completed'. PROCESS-MATRIX-OPERATIONS. DISPLAY 'Processing matrix operations:' *> Calculate matrix sum MOVE 0 TO MATRIX-SUM PERFORM VARYING ROW-INDEX FROM 1 BY 1 UNTIL ROW-INDEX > MATRIX-SIZE PERFORM VARYING COL-INDEX FROM 1 BY 1 UNTIL COL-INDEX > MATRIX-SIZE ADD MATRIX-COLS(ROW-INDEX, COL-INDEX) TO MATRIX-SUM END-PERFORM END-PERFORM DISPLAY 'Matrix sum: ' MATRIX-SUM *> Find maximum value in matrix MOVE 0 TO MATRIX-ELEMENT PERFORM VARYING ROW-INDEX FROM 1 BY 1 UNTIL ROW-INDEX > MATRIX-SIZE PERFORM VARYING COL-INDEX FROM 1 BY 1 UNTIL COL-INDEX > MATRIX-SIZE IF MATRIX-COLS(ROW-INDEX, COL-INDEX) > MATRIX-ELEMENT MOVE MATRIX-COLS(ROW-INDEX, COL-INDEX) TO MATRIX-ELEMENT END-IF END-PERFORM END-PERFORM DISPLAY 'Maximum value in matrix: ' MATRIX-ELEMENT *> Process diagonal elements MOVE 0 TO MATRIX-SUM PERFORM VARYING ROW-INDEX FROM 1 BY 1 UNTIL ROW-INDEX > MATRIX-SIZE ADD MATRIX-COLS(ROW-INDEX, ROW-INDEX) TO MATRIX-SUM END-PERFORM DISPLAY 'Diagonal sum: ' MATRIX-SUM. DEMONSTRATE-BATCH-PROCESSING. DISPLAY 'Demonstrating batch processing with monitoring:' MOVE 0 TO RECORDS-PROCESSED MOVE 0 TO SUCCESSFUL-RECORDS MOVE 0 TO FAILED-RECORDS *> Process multiple batches PERFORM VARYING CURRENT-BATCH FROM 1 BY 1 UNTIL CURRENT-BATCH > 5 DISPLAY 'Processing batch: ' CURRENT-BATCH *> Process records in current batch PERFORM VARYING ROW-INDEX FROM 1 BY 1 UNTIL ROW-INDEX > BATCH-SIZE / 200 *> Simulate batch size ADD 1 TO RECORDS-PROCESSED *> Simulate processing with occasional failures IF FUNCTION MOD(RECORDS-PROCESSED, 7) = 0 ADD 1 TO FAILED-RECORDS DISPLAY 'Record ' RECORDS-PROCESSED ' failed processing' ELSE ADD 1 TO SUCCESSFUL-RECORDS END-IF *> Progress reporting every 100 records IF FUNCTION MOD(RECORDS-PROCESSED, 100) = 0 DISPLAY 'Progress: ' RECORDS-PROCESSED ' records processed' END-IF END-PERFORM DISPLAY 'Batch ' CURRENT-BATCH ' completed' DISPLAY 'Successful: ' SUCCESSFUL-RECORDS DISPLAY 'Failed: ' FAILED-RECORDS END-PERFORM DISPLAY 'Batch processing completed' DISPLAY 'Total records processed: ' RECORDS-PROCESSED DISPLAY 'Success rate: ' FUNCTION NUMVAL(SUCCESSFUL-RECORDS / RECORDS-PROCESSED * 100) '%'. DEMONSTRATE-ERROR-HANDLING. DISPLAY 'Demonstrating error handling with retry logic:' MOVE 0 TO ERROR-COUNT MOVE 0 TO RETRY-COUNT *> Simulate processing with error handling PERFORM VARYING ROW-INDEX FROM 1 BY 1 UNTIL ROW-INDEX > 20 OR ERROR-COUNT >= MAX-ERRORS *> Simulate operation that might fail IF FUNCTION MOD(ROW-INDEX, 4) = 0 DISPLAY 'Error occurred at iteration: ' ROW-INDEX ADD 1 TO ERROR-COUNT *> Implement retry logic MOVE 0 TO RETRY-COUNT PERFORM UNTIL RETRY-COUNT >= MAX-RETRIES ADD 1 TO RETRY-COUNT DISPLAY 'Retry attempt: ' RETRY-COUNT *> Simulate retry success after 2 attempts IF RETRY-COUNT >= 2 DISPLAY 'Retry successful' SUBTRACT 1 FROM ERROR-COUNT EXIT PERFORM END-IF END-PERFORM IF RETRY-COUNT >= MAX-RETRIES DISPLAY 'Max retries exceeded for iteration: ' ROW-INDEX END-IF ELSE DISPLAY 'Successful processing at iteration: ' ROW-INDEX END-IF IF ERROR-COUNT >= MAX-ERRORS DISPLAY 'Maximum error threshold reached' SET TOO-MANY-ERRORS TO TRUE END-IF END-PERFORM DISPLAY 'Error handling demonstration completed' DISPLAY 'Final error count: ' ERROR-COUNT. DEMONSTRATE-COMPLEX-CONDITIONS. DISPLAY 'Demonstrating complex conditional processing:' SET PROCESSING-ACTIVE TO TRUE SET ERRORS-ACCEPTABLE TO TRUE MOVE 0 TO ROW-INDEX *> Complex loop with multiple exit conditions PERFORM UNTIL PROCESSING-DONE OR TOO-MANY-ERRORS OR ROW-INDEX > 100 ADD 1 TO ROW-INDEX *> Simulate complex processing logic EVALUATE TRUE WHEN ROW-INDEX < 25 DISPLAY 'Phase 1 processing: ' ROW-INDEX WHEN ROW-INDEX < 50 DISPLAY 'Phase 2 processing: ' ROW-INDEX *> Simulate occasional errors in phase 2 IF FUNCTION MOD(ROW-INDEX, 8) = 0 ADD 1 TO ERROR-COUNT END-IF WHEN ROW-INDEX < 75 DISPLAY 'Phase 3 processing: ' ROW-INDEX WHEN OTHER DISPLAY 'Final phase processing: ' ROW-INDEX *> Check for completion condition IF ROW-INDEX >= 90 SET PROCESSING-DONE TO TRUE DISPLAY 'Processing completed successfully' END-IF END-EVALUATE *> Check error threshold IF ERROR-COUNT >= MAX-ERRORS SET TOO-MANY-ERRORS TO TRUE DISPLAY 'Processing terminated due to errors' END-IF *> Progress reporting IF FUNCTION MOD(ROW-INDEX, 10) = 0 DISPLAY 'Progress checkpoint: ' ROW-INDEX DISPLAY 'Current error count: ' ERROR-COUNT END-IF END-PERFORM DISPLAY 'Complex conditional processing completed' DISPLAY 'Final iteration count: ' ROW-INDEX DISPLAY 'Processing status: ' IF PROCESSING-DONE DISPLAY 'COMPLETED SUCCESSFULLY' ELSE IF TOO-MANY-ERRORS DISPLAY 'TERMINATED DUE TO ERRORS' ELSE DISPLAY 'TERMINATED DUE TO ITERATION LIMIT' END-IF END-IF.

Best Practices and FAQ

Best Practices
  • • Always use END-PERFORM for inline PERFORM blocks
  • • Implement proper loop variable management
  • • Use meaningful condition checks
  • • Avoid infinite loops with proper termination
  • • Consider performance in nested loops
Common Mistakes
  • • Omitting END-PERFORM in complex structures
  • • Poor loop variable initialization
  • • Infinite loop conditions
  • • Inefficient nested loop design
  • • Missing boundary condition checks