1

If a table element (table without an index) is accessed using an index of another table it can give a Table overflow error on IBM Host. But the same program does not result in a crash or a message (even with debug options) when using GnuCOBOL (formerly OpenCOBOL).

e.g.

    IDENTIFICATION DIVISION.
    PROGRAM-ID.    TSTPROGX.
    DATA DIVISION.
    WORKING-STORAGE SECTION.
    01  IX                         PIC 9(04) COMP VALUE ZERO.
    01  VARS.
        05  S-PART-C.
            10  S-DETAIL      OCCURS 100 TIMES
                                    INDEXED BY S-SUB.
                15  S-ACTUAL  PIC 9(06) VALUE ZERO.
                15  S-ACTUAL-A
                                    REDEFINES S-ACTUAL
                                    PIC X(06).
                15  S-GRADE   PIC X(02) VALUE LOW-VALUE.
        05  POS-USED-ARRAY          PIC X(999)
                                   VALUE SPACE.
        05  FILLER                  REDEFINES POS-USED-ARRAY
                                              OCCURS 999.
            10  FILLER-X            PIC X .
                88  POSITIONS-USED-X          VALUE 'T'.
    PROCEDURE DIVISION.
        SET S-SUB TO 1
        PERFORM VARYING IX FROM 1 BY 1 UNTIL IX > 999
           SET S-SUB TO IX
           SET POSITIONS-USED-X(S-SUB) TO TRUE
           DISPLAY IX ":" FILLER-X(S-SUB)
        END-PERFORM
        GOBACK.

Is there a compiler option to issue warnings to avoid this kind of usage?

This error can be avoided by using the right usage.i.e, using the variable 'I-X', instead of using the index(S-SUB) of a different table.

SET POSITIONS-USED-X(I-X) TO TRUE

In general, exchanging index of independent tables(of different size) seems to be erroneous.

Bill Woodger
  • 12,968
  • 4
  • 38
  • 47
cobp
  • 772
  • 1
  • 5
  • 19
  • No pos is not an index defined for the table, it is just a variable. – cobp Apr 07 '16 at 19:03
  • I can't reproduce what you suggest. Can you post a short example, with the output it produces and the statement you use to compile it, please? – Bill Woodger Apr 08 '16 at 13:57
  • included full program in description. In Host , it crashed at index 125, but the referenced table size is 999. But that table size is 100, whose index is being used to refer the table. – cobp Apr 11 '16 at 13:04

1 Answers1

3

Presuming that by Host you mean Mainframe, using Enterprise COBOL, the link I originally included has the answer for you.

In Enterprise COBOL, you can use an index from one table to reference data on another table, even one which does not have an index (like your example), but unless the lengths of the data subordinate to the OCCURS is the same you will not get the results you expect.

With Enterprise COBOL and compiler option SSRANGE the code in your question will fail (as you are aware). Where will it fail? The length of the OCCURS associated with the index S-SUB is eight bytes. That length is effectively "inbuilt" into the index S-SUB. Dividing 999 (length of second table) by eight yields 124 (ignore the remainder), so an S-SUB being SET to 124 will be OK, and SET to 125 will not, because 125 will start at by 1,000, and you only have 999 bytes.

In GnuCOBOL the index does not have the length inbuilt, it is a simple integer relating directly to the occurence in the table. However, having got up to 100, you start overflowing the first table (where there is no compiler/run-time check) and 125 references later you go beyond the end of the second table, and with -g in your compile options will get a crash depending on how (and how much) the storage is allocated in the C program generated by the GnuCOBOL compiler. 225 would be the first point at which a crash could occur, but it may not do so at that point, and it may, or may not, later.

Basically, there's no way you can really expect the code to work, which you know, you just want to know how to set the compiler to check for it with GnuCOBOL. Currently, you can't.

Usually there is a field defined to hold the maximum entries in a table, and another defined to say how many are being used. When using entries, you first check to see the table is not full.

You could use LENGTH OF/FUNCTION LENGTH to protect against going over the end of a table as well.

You could combine the two approaches.

You just don't have a switch for GnuCOBOL that helps you here. The -g goes down to the C compiler. It gives you something, but not everything, and just depends.

Also, it is not, to my mind, a good idea to have a data-name which you use for subscripting named IX and an index named S-SUB. That will confuse a human reader of a program.

See this answer: https://stackoverflow.com/a/36254166/1927206 for some detail about using indexes from different tables.

IBM Enterprise COBOL can check that storage referenced using an index is within the table that the referenced-element is subordinate to. This is done with compiler option SSRANGE. If data outside the table is referenced (by any manner of subscripting, or by reference-modification) a run-time diagnostic message is produced. In all but the latest Enterprise COBOL compilers, that problem will cause an "abend" (an "abnormal end"). With the latest compilers, there are some sub-options to give more control.

This is not strictly checking the "bounds" of a table. For a one-dimensional table, the table-reference checking coincides with bounds-checking. For a multi-dimensional table it does not. The second and subsequent levels of subscript can be "wrong", but unless they cause a reference outside the table, this is unproblematic.

GnuCOBOL/OpenCOBOL does not have any checking for the use of subscripts or the reference of a table by subscripting/reference-modification. If you wanted to consider adding this yourself, you would be more than welcome. Or you could post it as a feature request. Visit https://sourceforge.net/p/open-cobol/discussion/?source=navbaring, but not everything.

See this answer: https://stackoverflow.com/a/36254166/1927206 for some detail about using indexes from different tables.

IBM Enterprise COBOL can check that storage referenced using an index is within the table that the referenced-element is subordinate to. This is done with compiler option SSRANGE. If data outside the table is referenced (by any manner of subscripting, or by reference-modification) a run-time diagnostic message is produced. In all but the latest Enterprise COBOL compilers, that problem will cause an "abend" (an "abnormal end"). With the latest compilers, there are some sub-options to give more control.

This is not strictly checking the "bounds" of a table. For a one-dimensional table, the table-reference checking coincides with bounds-checking. For a multi-dimensional table it does not. The second and subsequent levels of subscript can be "wrong", but unless they cause a reference outside the table, this is unproblematic.

GnuCOBOL/OpenCOBOL does not have any checking for the use of subscripts or the reference of a table by subscripting/reference-modification. If you wanted to consider adding this yourself, you would be more than welcome. Or you could post it as a feature request. Visit https://sourceforge.net/p/open-cobol/discussion/?source=navbar

Community
  • 1
  • 1
Bill Woodger
  • 12,968
  • 4
  • 38
  • 47
  • Problem is with the usage of index to a table of different dimension. So one would not expect a overflow issue here, becaus index value is not beyond table dimension. Table overflow issues are normally caught, when I compile GNUCOBOL with debug options(-g) . So I think the implementation of INDEX is different in GNU COBOL. – cobp Apr 07 '16 at 18:58
  • OK, so post the question on at the link at the bottom of my answer. – Bill Woodger Apr 07 '16 at 20:40
  • "In GnuCOBOL the index does not have the length inbuilt, it is a simple integer relating directly to the occurence in the table". So the issue here is that two compilers behave differently(please do not confuse it with bound overflow issue here). btw, with " -g -debug" I could consistently catch bound exception. './TSTPROGX.cbl:44: libcob: Subscript of 'S-ACTUAL' out of bounds: 101' (For the first table check, not in the given example). – cobp Apr 13 '16 at 16:53
  • 1
    Yes, they behave differently, as is detailed in the answer linked-to. To the COBOL Standard, it is down to the implementor to decide what the index contains. The two implementors have made different decisions. It is only through two Language Extensions (in both compilers) that your code even compiles. – Bill Woodger Apr 13 '16 at 18:23
  • I'm lost as to whether or not you have a problem with -g. I was using different code, I'll try to find time to try with your code. – Bill Woodger Apr 13 '16 at 18:24
  • what I meant was that the issue of table overflow can always be caught by using "-g -debug" options in GnuCOBOL. I modify the code to make an overflow in GnuCOBOL and error message was the similar one that might get using IBM COBOL with SSRANGE option. './TSTPROGX.cbl:44: libcob: Subscript of 'S-ACTUAL' out of bounds: 101' – cobp Apr 17 '16 at 10:35