MainframeMaster
MainframeMaster

COBOL Tutorial

Progress0 of 0 lessons

COBOL UNTIL Clause

The UNTIL clause in COBOL is used with the PERFORM statement to create loops that continue executing until a specified condition becomes true. Unlike loops that run while a condition is true, UNTIL loops run while the condition is false, stopping when the condition becomes true. Understanding UNTIL is essential for creating conditional loops, processing data until a termination condition is met, and implementing iterative logic in mainframe COBOL programs.

What is the UNTIL Clause?

The UNTIL clause creates a loop that executes repeatedly until a condition becomes true. Key characteristics:

  • Condition tested at end: The condition is evaluated after each iteration (TEST AFTER is default)
  • Loops while false: Continues executing while the condition is false
  • Stops when true: Exits the loop when the condition becomes true
  • At least one execution: With default TEST AFTER, the loop body executes at least once if the condition starts false
  • Flexible conditions: Can use any valid COBOL condition (comparisons, class tests, logical operators)

UNTIL is ideal for scenarios where you want to "keep going until something happens" rather than "keep going while something is true."

Basic UNTIL Syntax

The basic syntax for PERFORM UNTIL is:

cobol
1
2
3
4
5
6
7
8
9
10
PERFORM paragraph-name UNTIL condition *> Or with inline code: PERFORM statement-1 statement-2 ... UNTIL condition END-PERFORM

Components:

  • PERFORM: The statement that initiates the loop
  • paragraph-name or statements: The code to execute repeatedly (paragraph/section name or inline statements)
  • UNTIL condition: The condition that, when true, causes the loop to exit
  • END-PERFORM: Required when using inline statements (not needed for paragraph/section names)

Simple UNTIL Examples

Example 1: Processing Records Until End of File

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
WORKING-STORAGE SECTION. 01 END-OF-FILE PIC X VALUE 'N'. 01 RECORD-COUNT PIC 9(5) VALUE ZERO. PROCEDURE DIVISION. MAIN-PARA. OPEN INPUT INPUT-FILE READ INPUT-FILE AT END MOVE 'Y' TO END-OF-FILE END-READ PERFORM PROCESS-RECORD UNTIL END-OF-FILE = 'Y' DISPLAY 'Records processed: ' RECORD-COUNT CLOSE INPUT-FILE STOP RUN. PROCESS-RECORD. ADD 1 TO RECORD-COUNT *> Process the record... READ INPUT-FILE AT END MOVE 'Y' TO END-OF-FILE END-READ.

In this example:

  • END-OF-FILE is initialized to 'N' (not end of file)
  • PERFORM PROCESS-RECORD UNTIL END-OF-FILE = 'Y' continues processing records until the end-of-file flag is set to 'Y'
  • The loop continues while END-OF-FILE is not equal to 'Y' (i.e., while it's 'N')
  • The loop stops when END-OF-FILE becomes 'Y' (end of file reached)
  • At least one record is processed because the condition is tested at the end of each iteration

Example 2: Counting Until a Limit

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
WORKING-STORAGE SECTION. 01 COUNTER PIC 9(3) VALUE 1. 01 MAX-COUNT PIC 9(3) VALUE 10. PROCEDURE DIVISION. MAIN-PARA. PERFORM DISPLAY-COUNT UNTIL COUNTER > MAX-COUNT DISPLAY 'Counting complete' STOP RUN. DISPLAY-COUNT. DISPLAY 'Count: ' COUNTER ADD 1 TO COUNTER.

This loop:

  • Starts with COUNTER = 1
  • Continues while COUNTER is not greater than MAX-COUNT (i.e., COUNTER <= 10)
  • Stops when COUNTER becomes greater than MAX-COUNT (i.e., COUNTER > 10)
  • Executes 10 times, displaying counts 1 through 10

UNTIL with Inline Statements

You can use UNTIL with inline statements using END-PERFORM:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
WORKING-STORAGE SECTION. 01 USER-INPUT PIC X(10). 01 VALID-INPUT PIC X VALUE 'N'. PROCEDURE DIVISION. MAIN-PARA. PERFORM DISPLAY 'Enter a value: ' ACCEPT USER-INPUT IF USER-INPUT NOT = SPACES MOVE 'Y' TO VALID-INPUT END-IF UNTIL VALID-INPUT = 'Y' END-PERFORM DISPLAY 'Valid input received: ' USER-INPUT STOP RUN.

This loop:

  • Prompts for input and accepts user input
  • Validates that input is not empty (spaces)
  • Continues until valid input is received (VALID-INPUT = 'Y')
  • Uses END-PERFORM to mark the end of inline statements

UNTIL with VARYING

You can combine UNTIL with VARYING to create loops that both increment a counter and check a condition:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
WORKING-STORAGE SECTION. 01 COUNTER PIC 9(3). 01 SUM PIC 9(5) VALUE ZERO. PROCEDURE DIVISION. MAIN-PARA. PERFORM VARYING COUNTER FROM 1 BY 1 UNTIL COUNTER > 100 COMPUTE SUM = SUM + COUNTER END-PERFORM DISPLAY 'Sum of 1 to 100: ' SUM STOP RUN.

This loop:

  • VARYING COUNTER FROM 1 BY 1 initializes COUNTER to 1 and increments by 1 each iteration
  • UNTIL COUNTER > 100 stops when COUNTER exceeds 100
  • Executes 100 times (COUNTER values 1 through 100)
  • Calculates the sum of numbers from 1 to 100

VARYING with Different Increments

cobol
1
2
3
4
5
6
7
8
9
10
11
12
WORKING-STORAGE SECTION. 01 COUNTER PIC 9(3). PROCEDURE DIVISION. MAIN-PARA. *> Count by 5s until reaching 50 PERFORM VARYING COUNTER FROM 5 BY 5 UNTIL COUNTER > 50 DISPLAY 'Count: ' COUNTER END-PERFORM STOP RUN.

This displays: 5, 10, 15, 20, 25, 30, 35, 40, 45, 50. The loop increments by 5 each iteration until COUNTER exceeds 50.

TEST BEFORE vs TEST AFTER

COBOL allows you to control when the condition is tested:

TEST AFTER (Default)

The condition is tested at the end of each iteration. The loop body always executes at least once:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
WORKING-STORAGE SECTION. 01 COUNTER PIC 9(3) VALUE 10. PROCEDURE DIVISION. MAIN-PARA. *> Default: TEST AFTER PERFORM DISPLAY-COUNT UNTIL COUNTER > 5 *> This executes once even though COUNTER (10) > 5 initially STOP RUN. DISPLAY-COUNT. DISPLAY 'Count: ' COUNTER.

Even though COUNTER (10) is already greater than 5, the loop executes once because the condition is tested after the loop body runs.

TEST BEFORE

The condition is tested before each iteration. The loop body may not execute if the condition is true initially:

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
WORKING-STORAGE SECTION. 01 COUNTER PIC 9(3) VALUE 10. PROCEDURE DIVISION. MAIN-PARA. *> TEST BEFORE: condition checked first PERFORM DISPLAY-COUNT WITH TEST BEFORE UNTIL COUNTER > 5 *> This does NOT execute because COUNTER (10) > 5 initially STOP RUN. DISPLAY-COUNT. DISPLAY 'Count: ' COUNTER.

With TEST BEFORE, the condition is checked first. Since COUNTER (10) is already greater than 5, the loop body never executes.

TEST AFTER vs TEST BEFORE Comparison
AspectTEST AFTER (Default)TEST BEFORE
When condition is testedAt the end of each iterationBefore each iteration
Minimum executionsAt least once (if condition starts false)Zero times (if condition starts true)
Use whenYou want loop to always run at least onceYou want to skip loop if condition is already true
SyntaxPERFORM ... UNTIL condition (default)PERFORM ... WITH TEST BEFORE UNTIL condition

Complex UNTIL Conditions

UNTIL can use complex conditions with logical operators:

Using AND

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
WORKING-STORAGE SECTION. 01 COUNTER PIC 9(3) VALUE 1. 01 FOUND-FLAG PIC X VALUE 'N'. PROCEDURE DIVISION. MAIN-PARA. PERFORM SEARCH-LOOP UNTIL COUNTER > 100 AND FOUND-FLAG = 'Y' STOP RUN. SEARCH-LOOP. *> Continue until COUNTER exceeds 100 OR item is found *> (Loop stops when COUNTER > 100 AND FOUND-FLAG = 'Y') *> This means: stop when BOTH conditions are true ADD 1 TO COUNTER.

The loop continues while either COUNTER is not greater than 100 OR FOUND-FLAG is not 'Y'. It stops only when both conditions are true simultaneously.

Using OR

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
WORKING-STORAGE SECTION. 01 END-OF-FILE PIC X VALUE 'N'. 01 ERROR-FLAG PIC X VALUE 'N'. PROCEDURE DIVISION. MAIN-PARA. PERFORM PROCESS-RECORD UNTIL END-OF-FILE = 'Y' OR ERROR-FLAG = 'Y' STOP RUN. PROCESS-RECORD. *> Stop if end of file OR error occurs *> Loop continues while BOTH are false *> Stops when EITHER becomes true.

The loop stops when either END-OF-FILE is 'Y' OR ERROR-FLAG is 'Y'. It continues only while both are false.

Using NOT

cobol
1
2
3
4
5
6
7
8
9
10
11
12
WORKING-STORAGE SECTION. 01 CONTINUE-FLAG PIC X VALUE 'Y'. PROCEDURE DIVISION. MAIN-PARA. PERFORM PROCESS-LOOP UNTIL NOT CONTINUE-FLAG = 'Y' *> Equivalent to: UNTIL CONTINUE-FLAG NOT = 'Y' *> Loop continues while CONTINUE-FLAG = 'Y' *> Stops when CONTINUE-FLAG is not 'Y' STOP RUN.

Using NOT inverts the condition. The loop continues while CONTINUE-FLAG is 'Y' and stops when it's not 'Y'.

Exiting UNTIL Loops Early

You can exit a PERFORM UNTIL loop before the condition becomes true:

Method 1: Setting the Condition Variable

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
WORKING-STORAGE SECTION. 01 END-FLAG PIC X VALUE 'N'. 01 COUNTER PIC 9(3) VALUE 1. PROCEDURE DIVISION. MAIN-PARA. PERFORM PROCESS-LOOP UNTIL END-FLAG = 'Y' STOP RUN. PROCESS-LOOP. ADD 1 TO COUNTER *> Exit early if counter reaches 50 IF COUNTER > 50 MOVE 'Y' TO END-FLAG END-IF *> Continue processing...

By setting END-FLAG to 'Y' when COUNTER exceeds 50, the loop exits at the end of the current iteration, even though the original condition might have been different.

Method 2: Using EXIT PERFORM

cobol
1
2
3
4
5
6
7
8
9
10
PROCEDURE DIVISION. MAIN-PARA. PERFORM *> Process item IF ERROR-CONDITION EXIT PERFORM END-IF *> More processing... UNTIL END-CONDITION END-PERFORM.

EXIT PERFORM immediately exits the current iteration and continues with the next iteration (or exits the loop if the UNTIL condition is now true).

UNTIL vs WHILE

Understanding when to use UNTIL vs WHILE:

UNTIL vs WHILE Comparison
AspectUNTILWHILE
Loop continues whileCondition is FALSECondition is TRUE
Loop stops whenCondition becomes TRUECondition becomes FALSE
Natural expression"Keep going until X happens""Keep going while X is true"
ExampleUNTIL END-OF-FILE = 'Y'WHILE NOT END-OF-FILE
ReadabilityBetter for "until something happens"Better for "while condition holds"

Choosing Between UNTIL and WHILE

Use UNTIL when:

  • You want to express "keep going until something happens"
  • The exit condition is a positive event (end of file, found item, error occurred)
  • You prefer testing for a termination condition

Use WHILE when:

  • You want to express "keep going while something is true"
  • The continuation condition is a positive state (data available, valid input, not done)
  • You prefer testing for a continuation condition

Common UNTIL Patterns

Pattern 1: File Processing

cobol
1
2
3
4
5
6
7
8
9
10
11
PERFORM READ-AND-PROCESS UNTIL END-OF-FILE = 'Y' READ-AND-PROCESS. READ INPUT-FILE AT END MOVE 'Y' TO END-OF-FILE END-READ IF END-OF-FILE NOT = 'Y' *> Process the record END-IF.

Pattern 2: Input Validation

cobol
1
2
3
4
5
6
7
8
9
10
11
MOVE 'N' TO VALID-INPUT PERFORM DISPLAY 'Enter value (1-100): ' ACCEPT USER-INPUT IF USER-INPUT IS NUMERIC IF USER-INPUT >= 1 AND USER-INPUT <= 100 MOVE 'Y' TO VALID-INPUT END-IF END-IF UNTIL VALID-INPUT = 'Y' END-PERFORM.

Pattern 3: Search Loop

cobol
1
2
3
4
5
6
7
8
9
10
11
MOVE 1 TO SEARCH-INDEX PERFORM SEARCH-LOOP UNTIL SEARCH-INDEX > MAX-ITEMS OR ITEM-FOUND = 'Y' SEARCH-LOOP. IF SEARCH-ARRAY(SEARCH-INDEX) = TARGET-VALUE MOVE 'Y' TO ITEM-FOUND ELSE ADD 1 TO SEARCH-INDEX END-IF.

Best Practices for UNTIL Loops

Follow these best practices when using UNTIL:

  • Initialize loop control variables: Always initialize variables used in the UNTIL condition before the loop starts. Uninitialized variables can cause unpredictable behavior.
  • Ensure condition can become true: Make sure the UNTIL condition can actually become true, or you'll create an infinite loop. Test with edge cases to verify termination.
  • Use meaningful condition names: Name flags and variables descriptively (END-OF-FILE, FOUND-FLAG) to make the UNTIL condition self-documenting.
  • Remember TEST AFTER default: Be aware that UNTIL with default TEST AFTER always executes at least once. Use TEST BEFORE if you need to skip execution when the condition is initially true.
  • Handle edge cases: Test with empty data, boundary values, and conditions that are true from the start to ensure correct behavior.
  • Use appropriate logical operators: Choose AND, OR, and NOT carefully to express the correct exit condition. Test complex conditions thoroughly.
  • Document exit conditions: Add comments explaining when and why the loop should exit, especially for complex conditions.
  • Avoid infinite loops: Ensure variables in the condition are modified within the loop body so the condition can eventually become true.
  • Consider performance: For large iterations, consider the performance impact. Use efficient conditions and avoid unnecessary operations in the loop body.
  • Test termination: Verify that loops terminate correctly with various input scenarios, including empty data and boundary conditions.

Common Mistakes with UNTIL

Avoid these common mistakes:

Mistake 1: Infinite Loop

cobol
1
2
3
4
5
6
7
8
9
*> WRONG: Condition never becomes true MOVE 1 TO COUNTER PERFORM PROCESS-LOOP UNTIL COUNTER = 0 PROCESS-LOOP. ADD 1 TO COUNTER *> COUNTER starts at 1 and only increases *> It will never equal 0 - INFINITE LOOP!

The condition COUNTER = 0 can never become true because COUNTER only increases. This creates an infinite loop.

Mistake 2: Forgetting TEST AFTER

cobol
1
2
3
4
5
6
7
8
9
10
11
*> WRONG: May execute when you don't want it to MOVE 100 TO COUNTER PERFORM PROCESS-LOOP UNTIL COUNTER > 50 *> Loop executes once even though COUNTER (100) > 50 *> CORRECT: Use TEST BEFORE PERFORM PROCESS-LOOP WITH TEST BEFORE UNTIL COUNTER > 50 *> Loop does not execute because condition is true initially

Mistake 3: Wrong Logical Operator

cobol
1
2
3
4
5
6
7
8
9
10
*> WRONG: Using AND when you mean OR PERFORM PROCESS-LOOP UNTIL END-OF-FILE = 'Y' AND ERROR-FLAG = 'Y' *> This requires BOTH to be true to exit *> If only one is true, loop continues forever *> CORRECT: Use OR PERFORM PROCESS-LOOP UNTIL END-OF-FILE = 'Y' OR ERROR-FLAG = 'Y' *> Exits when EITHER condition is true

Explain Like I'm 5: UNTIL

Think of UNTIL like playing a game:

  • PERFORM UNTIL is like saying "keep playing until something happens"
  • The condition is like a rule that says "stop when you reach the finish line"
  • You keep playing (executing the loop) while you haven't reached the finish line (condition is false)
  • You stop playing (exit the loop) when you reach the finish line (condition becomes true)
  • You always play at least once because you check if you're at the finish line after each turn, not before

So UNTIL is like a game where you keep taking turns until you win or reach a goal, and you always get to play at least one turn!

Practice Exercises

Complete these exercises to reinforce your understanding of UNTIL:

Exercise 1: Countdown Loop

Create a program that uses PERFORM UNTIL to count down from 10 to 1, displaying each number. The loop should stop when the counter reaches 0.

Exercise 2: Sum Until Limit

Create a program that uses PERFORM VARYING ... UNTIL to sum numbers from 1 to 100. Display the final sum.

Exercise 3: Input Validation

Create a program that uses PERFORM UNTIL to repeatedly prompt for user input until a valid number between 1 and 10 is entered. Use a flag to track valid input.

Exercise 4: Search with UNTIL

Create a program that uses PERFORM UNTIL to search through an array until either the target value is found or the end of the array is reached. Use OR in the UNTIL condition.

Exercise 5: TEST BEFORE vs TEST AFTER

Create two versions of a loop: one with TEST AFTER (default) and one with TEST BEFORE. Initialize a counter to 10 and loop UNTIL counter > 5. Observe the difference in execution.

Test Your Knowledge

1. What does PERFORM UNTIL do?

  • Executes a loop while a condition is true
  • Executes a loop until a condition becomes true
  • Executes a loop a fixed number of times
  • Executes a loop forever

2. When is the UNTIL condition tested?

  • Before the loop body executes
  • At the end of each iteration
  • Only on the first iteration
  • Only on the last iteration

3. What happens if the UNTIL condition is true from the start?

  • The loop never executes
  • The loop executes once
  • The loop executes forever
  • An error occurs

4. How do you create a loop that increments a counter until it reaches 10?

  • PERFORM VARYING COUNTER FROM 1 BY 1 UNTIL COUNTER > 10
  • PERFORM VARYING COUNTER FROM 1 BY 1 UNTIL COUNTER = 10
  • PERFORM UNTIL COUNTER = 10
  • PERFORM 10 TIMES

5. What is the difference between UNTIL and WHILE?

  • There is no difference
  • UNTIL loops while condition is false, WHILE loops while condition is true
  • UNTIL is faster than WHILE
  • UNTIL can only be used with PERFORM, WHILE cannot

6. How do you exit a PERFORM UNTIL loop early?

  • Use EXIT PERFORM
  • Set the UNTIL condition to true
  • Use STOP RUN
  • Both A and B are correct

Related Concepts

Related Pages