Beroli
Beroli

Reputation: 35

What part of this code is causing an infinite loop?

I'm sure there's a simpler way to do this, but I'm new to COBOL. Some part of this code causes an infinite loop, before the part where it writes anything to the write file, but I can't see where; I've tried rewriting multiple parts of it that looked like they might be the problem. What am I missing?

The specific problem is that it causes an infinite loop, that is when I run the program, it runs until hard-shutdown and does nothing. The desired behavior is for the program to access the Ch10_payroll.DAT file, read information on the annual salaries of the group of people in each of nine territories, and write the total annual salaries of each territory to the Ch10_payroll.RPT file.

   ...
   Working-Storage Section.
   ...
   01  WS-Total-1                      PIC 9(6)            Value Zeroes.
   01  WS-Total-2                      PIC 9(6)            Value Zeroes.
   01  WS-Total-3                      PIC 9(6)            Value Zeroes.
   01  WS-Total-4                      PIC 9(6)            Value Zeroes.
   01  WS-Total-5                      PIC 9(6)            Value Zeroes.
   01  WS-Total-6                      PIC 9(6)            Value Zeroes.
   01  WS-Total-7                      PIC 9(6)            Value Zeroes.
   01  WS-Total-8                      PIC 9(6)            Value Zeroes.
   01  WS-Total-9                      PIC 9(6)            Value Zeroes.
   01  WS-Territory-No                 PIC 99              Value Zeroes.
   ...
   01  Detail-Line.
       05                              PIC X(3)            Value Spaces.
       05  Territory-No-Out            PIC 99.
       05                              PIC X(17)           Value Spaces.
       05  Current-Territory-Total     PIC $ZZZ,ZZZ.99.

   ...
  * This section will list the inflation rate and item cost for each projected year.
   Procedure Division.

   ...

   700-HDR-Module.
   Perform Until Territory-No-Out Equals 10
       If Territory-No-Out Equals 01 Then Move WS-Total-1 To Current-Territory-Total
       If Territory-No-Out Equals 02 Then Move WS-Total-2 To Current-Territory-Total
       If Territory-No-Out Equals 03 Then Move WS-Total-3 To Current-Territory-Total
       If Territory-No-Out Equals 04 Then Move WS-Total-4 To Current-Territory-Total
       If Territory-No-Out Equals 05 Then Move WS-Total-5 To Current-Territory-Total
       If Territory-No-Out Equals 06 Then Move WS-Total-6 To Current-Territory-Total
       If Territory-No-Out Equals 07 Then Move WS-Total-7 To Current-Territory-Total
       If Territory-No-Out Equals 08 Then Move WS-Total-8 To Current-Territory-Total
       If Territory-No-Out Equals 09 Then Move WS-Total-9 To Current-Territory-Total
       Write Print-Rec From HDR-1
       Write Print-Rec From Column-Headings
           After Advancing 2 Lines
       Write Print-Rec From Detail-Line
           After Advancing 2 Lines
       At End-Of-Page Add 1 To Page-Text
       Add 1 To Territory-No-Out
   End-Perform
   Move 'NO ' To Are-There-More-Records.

   ...

Upvotes: 2

Views: 1058

Answers (1)

Bill Woodger
Bill Woodger

Reputation: 13076

You have this:

   If Territory-No-Out Equals 01 Then Move WS-Total-1 To Current-Territory-Total
   If Territory-No-Out Equals 02 Then Move WS-Total-2 To Current-Territory-Total
   ...

An IF is terminated by a full-stop/period or by an END-IF. If another IF (or any conditional statement) is encountered before then, it is "nested", it's execution is conditional on the previous condition being true.

Your nested-IF is testing the same field for multiple different values, and you have no END-IFs or full-stops/periods. So your code which you think is nothing to do with the IFs is in fact never, ever, ever, going to be executed.

You also have this:

Write Print-Rec From Detail-Line
       After Advancing 2 Lines
   At End-Of-Page Add 1 To Page-Text

The AT END-OF-PAGE is an imperative statement. Again that is terminated by a scope-terminator (in this case END-WRITE) or by a full-stop/period. So once you are over the IF-problem, you have this one as well.

Terminate all conditions with their scope-terminator. Terminate all imperative statements with their scope-terminator. Terminate paragraphs, SECTIONs and program with a full-stop/period.

When you have a Big Fat Loop (BFL) in a program, it is usually simple to find where the loop is. You then need to find out exactly why the loop doesn't terminate.

If you have a BFL and the run-time does not tell you where, or you cannot work out where from the failure information, or the output created, then you look at all the places in your program where you have a looping-construct.

You look for GO TO. You look for "fall-through". You look for PERFORM ... UNTIL ... and you look for possible recursive PERFORM.

You have only two of the above. The first is involving the READ. If you remove (comment out) any other processing than related to the file, you can demonstrate to yourself that the read-loop is working. Which then means it is the other one.

You then look at that code, to see how the termination condition is never reached. In this case you get "that ADD 1 can't be being executed". Whether you then work out about the scope-termination depends on what you know already. So if you don't know, you look at your teaching notes and your language manuals.

If you need lots of IFs testing a condition on the same field, look at using EVALUATE (with END-EVALUATE).

However, for your task, look at using a table with OCCURS. This will save you naming individual totals, and requiring those whose strings of IF anyway.

Look at some of the other COBOL questions here. Learn about FILE STATUS and such things.

Upvotes: 5

Related Questions