PERFORM UNTIL: run the statements again and again until the condition is satisfied.This guide explains the UNTIL phrase of the COBOL PERFORM statement with simple examples. It keeps the focus on loop control: the condition, TEST BEFORE, TEST AFTER, inline loops, paragraph loops, and the mistakes that cause endless loops.
What PERFORM UNTIL Means
PERFORM UNTIL repeats a block of code or a named paragraph until a condition is true. IBM documents that when the condition is true, control passes to the next executable statement after the PERFORM.
PERFORM UNTIL END-OF-FILEREAD CUSTOMER-FILEAT ENDSET END-OF-FILE TO TRUENOT AT ENDPERFORM 200-PROCESS-CUSTOMEREND-READEND-PERFORM.
The loop continues while END-OF-FILE is false. It stops after the READ reaches end of file and the program sets the condition-name to true.
PERFORM UNTIL Syntax
The inline form keeps the looped statements directly under the PERFORM. It ends with END-PERFORM, which makes the loop boundary easy to see.
PERFORM [WITH TEST BEFORE | WITH TEST AFTER]UNTIL conditionstatement-1statement-2END-PERFORM.
The out-of-line form runs a paragraph or a range of paragraphs until the condition becomes true.
PERFORM 300-CALCULATE-TOTALUNTIL WS-DONE = "Y".
TEST BEFORE Is the Default
If you do not code WITH TEST BEFORE or WITH TEST AFTER, COBOL assumes TEST BEFORE. The condition is checked before the first execution. If the condition is already true, the loop body does not run at all.
MOVE 6 TO WS-COUNT.PERFORM WITH TEST BEFOREUNTIL WS-COUNT > 5DISPLAY "COUNT=" WS-COUNTADD 1 TO WS-COUNTEND-PERFORM.
This loop displays nothing because WS-COUNT > 5 is already true before the loop starts. That behavior is correct, but it surprises many beginners.
TEST AFTER Runs at Least Once
WITH TEST AFTER checks the condition after the statements run. That means the body runs at least once, even when the condition is already true at entry.
MOVE 6 TO WS-COUNT.PERFORM WITH TEST AFTERUNTIL WS-COUNT > 5DISPLAY "COUNT=" WS-COUNTADD 1 TO WS-COUNTEND-PERFORM.
This loop displays one line for COUNT=6, then stops. Use TEST AFTER only when one execution is required, such as prompting once before checking whether the user wants to continue.
File Reading Example
The most common mainframe use is a file loop. The file status and end-of-file flag should be initialized before the loop, then changed inside the loop.
01 WS-CUSTOMER-STATUS PIC X(02).01 WS-END-OF-FILE PIC X VALUE "N".88 END-OF-FILE VALUE "Y".88 MORE-RECORDS VALUE "N".PROCEDURE DIVISION.SET MORE-RECORDS TO TRUE.PERFORM UNTIL END-OF-FILEREAD CUSTOMER-FILEAT ENDSET END-OF-FILE TO TRUENOT AT ENDPERFORM 200-PROCESS-CUSTOMEREND-READEND-PERFORM.
This pattern is readable because the condition says what stops the loop. The loop does not depend on a hidden counter or an unclear flag name.
Counter Loop Example
PERFORM UNTIL can also control a counter. Initialize the counter before the loop and change it inside the loop. Without the change, the loop can run forever.
MOVE 1 TO WS-SUB.PERFORM UNTIL WS-SUB > 10DISPLAY "TABLE ENTRY " WS-SUBADD 1 TO WS-SUBEND-PERFORM.
For a pure counter loop, PERFORM VARYING may be clearer. Use the plain UNTIL form when the stop condition is tied to a flag, file status, response code, or business rule.
Inline PERFORM vs Paragraph PERFORM
| Form | Use it when | Watch for |
|---|---|---|
Inline PERFORM UNTIL | The loop body is short and belongs in one place. | Use END-PERFORM and keep nested statements readable. |
Paragraph PERFORM UNTIL | The loop body is reused or has a clear paragraph name. | Avoid wide THRU ranges that make control flow hard to follow. |
IBM notes that Enterprise COBOL supports both inline and out-of-line PERFORM. For modern code, a short inline loop is often easier to read, while a named paragraph can still be useful for a business step such as 200-PROCESS-CUSTOMER.
PERFORM UNTIL EXIT
UNTIL EXIT creates a loop that does not end from a normal condition. IBM warns that the program must reach a real escape path. In an inline loop, that usually means EXIT PERFORM.
PERFORM UNTIL EXITACCEPT WS-REPLYIF WS-REPLY = "Q"EXIT PERFORMEND-IFPERFORM 100-HANDLE-REPLYEND-PERFORM.
Use this form sparingly. A named condition such as UNTIL END-OF-FILE or UNTIL WS-REPLY = "Q" is usually easier for the next developer to inspect.
Common Mistakes
Forgetting to Change the Loop Condition
If the condition never becomes true, the loop never ends. Update the counter, set the end-of-file flag, or change the response field inside the loop.
Using TEST AFTER by Accident
TEST AFTER guarantees one execution. That is useful only when one pass is required. For file reads and most validation loops, TEST BEFORE is usually safer.
Hiding Logic in a Wide THRU Range
PERFORM A-PARA THRU Z-PARA can execute every paragraph between those names. Keep paragraph ranges tight, or use inline PERFORM when the loop belongs in one place.
Related COBOL Lessons
For the broader loop family, read COBOL PERFORM statement, COBOL basic PERFORM, COBOL PERFORM TIMES phrase, and PERFORM VARYING in COBOL. For condition logic, continue with COBOL IF statement and COBOL EVALUATE statement.
FAQ
What is PERFORM UNTIL in COBOL?
PERFORM UNTIL repeats a block of statements or a paragraph until the specified condition becomes true.
Is TEST BEFORE or TEST AFTER the default?
TEST BEFORE is the default. COBOL checks the condition before the first execution unless WITH TEST AFTER is coded.
When should I use TEST AFTER?
Use TEST AFTER when the loop body must run at least once, such as asking for input once before checking whether the user wants to quit.
How do I prevent an endless PERFORM UNTIL loop?
Initialize the condition before the loop and make sure the loop body can make the condition true. For file loops, set an end-of-file flag in the AT END path.
References
For exact syntax and current compiler behavior, use IBM documentation for PERFORM with UNTIL phrase, using PERFORM, and IBM's coding a loop examples.
Write the condition so it says exactly when the loop must stop, then make sure the code inside the loop can make that condition true.