Quiz — Chapter 7: Iteration Patterns

Multiple Choice

1. What is the default test mode for PERFORM ... UNTIL?

a) TEST AFTER b) TEST BEFORE c) TEST BOTH d) It depends on the compiler

2. After the following code executes, what is the value of WS-IDX?

       PERFORM 2100-PROCESS
           VARYING WS-IDX FROM 1 BY 1
           UNTIL WS-IDX > 5

a) 5 b) 6 c) 0 d) Undefined

3. In a PERFORM VARYING ... AFTER construct, which identifier varies faster?

a) The VARYING identifier b) The AFTER identifier c) They vary at the same rate d) It depends on the FROM/BY values

4. What is the "priming read" pattern?

a) Reading the last record before closing the file b) Reading the first record before entering a TEST BEFORE loop c) Reading the file twice for verification d) Initializing the read buffer with zeros

5. How many times is paragraph 2100-PROCESS executed?

       MOVE 0 TO WS-COUNT
       PERFORM 2100-PROCESS
           UNTIL WS-COUNT > 0

a) 0 times b) 1 time c) Infinite times (unless WS-COUNT is modified in 2100-PROCESS) d) It depends on the compiler

6. What does EXIT PERFORM CYCLE do?

a) Exits the program b) Exits the innermost inline PERFORM and continues after END-PERFORM c) Skips the rest of the current iteration and begins the next iteration d) Pauses the loop for one cycle

7. Which of the following is a valid reason to use PERFORM THRU?

a) It executes paragraphs in reverse order b) It provides a clean exit point for guard clause patterns c) It is faster than basic PERFORM d) It is required for inline PERFORMs

8. When should you use PERFORM ... TIMES instead of PERFORM ... UNTIL?

a) When you need early exit capability b) When the number of iterations is known and fixed, and all iterations must execute c) When processing sequential files d) Always — it is faster than PERFORM UNTIL

9. What is the primary risk of an infinite loop in a batch COBOL program?

a) The program displays an error message b) The program consumes CPU, holds file locks, and blocks downstream jobs c) The program automatically restarts d) The mainframe shuts down

10. In the following code, what happens if WS-TABLE-SIZE is 0?

       PERFORM 2100-PROCESS
           WITH TEST AFTER
           VARYING WS-IDX FROM 1 BY 1
           UNTIL WS-IDX > WS-TABLE-SIZE

a) The paragraph is not executed b) The paragraph is executed once c) A compile error occurs d) An abend occurs

True or False

11. PERFORM ... TIMES can use a data item (not just a literal) to specify the number of iterations.

12. Modifying the VARYING counter inside the performed paragraph is a safe and recommended practice.

13. An inline PERFORM (with END-PERFORM) can contain nested inline PERFORMs.

14. EXIT PERFORM can be used with out-of-line (paragraph-based) PERFORM loops.

15. PERFORM VARYING ... AFTER is equivalent to a nested loop, with the AFTER identifier as the inner loop.

Short Answer

16. Explain the difference between the following two loop constructs. Under what circumstances would they produce different results?

      * Version A
       PERFORM 2100-PROCESS
           WITH TEST BEFORE
           UNTIL WS-FLAG = 'Y'

      * Version B
       PERFORM 2100-PROCESS
           WITH TEST AFTER
           UNTIL WS-FLAG = 'Y'

17. A batch program processes 2 million records nightly. The operations team reports that last night's run took 6 hours instead of the usual 45 minutes, and the checkpoint log showed the same account number repeating for 3 hours. Describe three defensive programming techniques that could have detected or prevented this problem.

18. Write the PERFORM VARYING statement that would traverse a three-dimensional table with dimensions: 4 departments, 12 months, and 5 expense categories. Identify which identifier varies fastest.

19. Explain why the following code has an off-by-one error, and provide the corrected version:

       PERFORM 2100-PROCESS
           VARYING WS-IDX FROM 1 BY 1
           UNTIL WS-IDX = WS-TABLE-SIZE

20. Compare inline PERFORM and out-of-line PERFORM. Give two scenarios where each is the better choice, and explain why.


Answer Key

1. b) TEST BEFORE is the default.

2. b) 6. The counter is incremented to 6, tested (6 > 5 is true), and the loop exits with WS-IDX = 6.

3. b) The AFTER identifier varies faster — it completes its full range for each value of the VARYING identifier.

4. b) Reading the first record before entering a TEST BEFORE loop, so the first record is available for processing when the loop begins.

5. a) 0 times. TEST BEFORE is the default. WS-COUNT is 0, and 0 > 0 is false, so the condition WS-COUNT > 0 is false, meaning the loop will execute. Wait — re-reading: UNTIL WS-COUNT > 0. WS-COUNT is 0. Is 0 > 0? No. So the UNTIL condition is false, meaning the loop body WILL execute. But then WS-COUNT is never modified (no mention of modification in 2100-PROCESS), so this would be infinite. The answer is c) Infinite times, unless WS-COUNT is modified in 2100-PROCESS.

Actually, let me reconsider. The question says WS-COUNT is 0 and we PERFORM UNTIL WS-COUNT > 0. With TEST BEFORE (default): check condition first. WS-COUNT = 0, is 0 > 0? No. So condition is NOT met, execute the paragraph. If 2100-PROCESS does not modify WS-COUNT, the loop is infinite. The answer is c).

6. c) Skips the rest of the current iteration and begins the next iteration (equivalent to continue in C/Java).

7. b) It provides a clean exit point for guard clause patterns using GO TO to the exit paragraph.

8. b) When the number of iterations is known and fixed, and all iterations must execute (no early exit needed).

9. b) The program consumes CPU, holds file locks, and blocks downstream jobs — a serious production incident.

10. b) The paragraph is executed once. TEST AFTER always executes at least once. After the first execution, WS-IDX is 2 (incremented by 1), and the condition 2 > 0 is true, so the loop exits.

11. True. The TIMES value can be a literal or a numeric data item.

12. False. Modifying the VARYING counter inside the performed paragraph produces unpredictable behavior and can cause infinite loops.

13. True. Inline PERFORMs can be nested within each other.

14. False. EXIT PERFORM only works within inline PERFORMs (between PERFORM and END-PERFORM). For out-of-line PERFORMs, you must use PERFORM THRU with GO TO to an exit paragraph.

15. True. The AFTER identifier completes its full range for each value of the VARYING identifier, equivalent to an inner nested loop.

16. Version A (TEST BEFORE) checks the condition before each execution. If WS-FLAG is already 'Y' when the PERFORM is first encountered, the paragraph is never executed (0 iterations). Version B (TEST AFTER) checks the condition after each execution. The paragraph is always executed at least once, even if WS-FLAG is already 'Y'. They produce different results when WS-FLAG = 'Y' before the loop begins: Version A executes 0 times, Version B executes 1 time.

17. Three defensive techniques: (1) Safety counter: Set a maximum iteration limit (e.g., 3 million) and terminate the loop with an error if exceeded. (2) Progress verification: Track the last account number processed and count consecutive repetitions; if the same account appears more than a threshold (e.g., 1000 times), terminate with an error. (3) Checkpoint logging with timing: Log progress every N records with timestamps; operations can detect when processing speed drops to zero (same record repeating). Additionally, a wall-clock timeout could be implemented at the JCL level.

18.

       PERFORM 2100-PROCESS-CELL
           VARYING WS-DEPT FROM 1 BY 1
           UNTIL WS-DEPT > 4
           AFTER WS-MONTH FROM 1 BY 1
           UNTIL WS-MONTH > 12
           AFTER WS-CATEGORY FROM 1 BY 1
           UNTIL WS-CATEGORY > 5

WS-CATEGORY varies fastest (innermost), then WS-MONTH, then WS-DEPT (outermost).

19. The UNTIL condition WS-IDX = WS-TABLE-SIZE causes the loop to exit when WS-IDX equals TABLE-SIZE, meaning the element at position TABLE-SIZE is never processed. This is an off-by-one error. Corrected:

       PERFORM 2100-PROCESS
           VARYING WS-IDX FROM 1 BY 1
           UNTIL WS-IDX > WS-TABLE-SIZE

20. Inline PERFORM is better when: (1) The loop body is short (1-5 statements) and purely local, e.g., accumulating a total across a table. Extracting one ADD statement to a separate paragraph adds unnecessary overhead and fragmentation. (2) When using EXIT PERFORM or EXIT PERFORM CYCLE for flow control within the loop.

Out-of-line PERFORM is better when: (1) The loop body is complex (>5-10 statements) with nested conditionals — a separate paragraph keeps the loop structure visible. (2) When the same logic needs to be called from multiple places in the program — a paragraph can be PERFORMed from anywhere.