使用另一个表中的索引

时间:2016-04-07 15:23:58

标签: cobol gnucobol

如果使用另一个表的索引访问表元素(没有索引的表),它可能会在IBM主机上产生表溢出错误。但是,当使用GnuCOBOL(以前称为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.

是否有编译器选项来发出警告以避免这种用法?

使用正确的用法可以避免此错误。使用变量'I-X',而不是使用不同表的索引(S-SUB)。

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

一般来说,交换独立表(不同大小)的索引似乎是错误的。

1 个答案:

答案 0 :(得分:3)

假设您使用Enterprise COBOL主机是指Mainframe,我最初提供的链接可以为您提供答案。

在Enterprise COBOL中,您可以使用一个表中的索引来引用另一个表上的数据,即使是没有索引的数据(如您的示例),但除非数据的长度从属于OCCURS是相同的你不会得到你期望的结果。

使用Enterprise COBOL和编译器选项SSRANGE,您问题中的代码将失败(如您所知)。它会在哪里失败?与索引S-SUB相关联的OCCURS的长度是八个字节。这个长度实际上是内置的"进入索引S-SUB。将999(第二个表的长度)除以8得到124(忽略余数),因此设置为124的S-SUB将为OK,而设置为125将不会,因为125将从1,000开始,并且您只有999字节。

在GnuCOBOL中,索引没有内置的长度,它是一个简单的整数,直接与表中的出现有关。但是,最多100个,你开始溢出第一个表(没有编译器/运行时检查)和125个引用,你超出了第二个表的末尾,并且在编译选项中使用-g将获得崩溃取决于GnuCOBOL编译器生成的C程序中存储的分配方式(以及多少)。 225可能是发生崩溃的第一个点,但在那时可能不会这样做,而且可能会或可能不会在以后发生。

基本上,您无法真正期望代码能够正常工作,您知道,您只想知道如何设置编译器以使用GnuCOBOL进行检查。目前,你不能。

通常会定义一个字段来保存表中的最大条目,另一个字段定义为表示正在使用的字段数。使用条目时,首先要检查表格是否已满。

您可以使用LENGTH OF / FUNCTION LENGTH来防止超越表格的结尾。

你可以将这两种方法结合起来。

你只是没有GnuCOBOL的开关来帮助你。 -g转到C编译器。它给了你一些东西,但不是一切,只是依赖。

另外,在我看来,最好不要使用一个用于下标的数据名称IX和一个名为S-SUB的索引。这将使人类读者对程序感到困惑。

有关使用不同表中的索引的详细信息,请参阅此答案:https://stackoverflow.com/a/36254166/1927206

IBM Enterprise COBOL可以检查使用索引引用的存储是否在被引用元素从属的表中。这是通过编译器选项SSRANGE完成的。如果引用表外的数据(通过任何方式的下标或通过引用修改),则会生成运行时诊断消息。除了最新的企业COBOL编译器之外,这个问题将导致一个" abend" ("异常结束")。使用最新的编译器,有一些子选项可以提供更多控制。

这不是严格检查"界限"一张桌子。对于一维表,表引用检查与边界检查一致。对于多维表,它没有。下标的第二级和后续级别可能是"错误",但除非它们在表格之外引起参考,否则这是没有问题的。

GnuCOBOL / OpenCOBOL没有通过下标/引用修改检查下标的使用或表的引用。如果你想考虑自己添加,你会非常欢迎。或者您可以将其作为功能请求发布。访问https://sourceforge.net/p/open-cobol/discussion/?source=navbaring,但不是所有内容。

有关使用不同表中的索引的详细信息,请参阅此答案:https://stackoverflow.com/a/36254166/1927206

IBM Enterprise COBOL可以检查使用索引引用的存储是否在被引用元素从属的表中。这是通过编译器选项SSRANGE完成的。如果引用表外的数据(通过任何方式的下标或通过引用修改),则会生成运行时诊断消息。除了最新的企业COBOL编译器之外,这个问题将导致一个" abend" ("异常结束")。使用最新的编译器,有一些子选项可以提供更多控制。

这不是严格检查"界限"一张桌子。对于一维表,表引用检查与边界检查一致。对于多维表,它没有。下标的第二级和后续级别可能是"错误",但除非它们在表格之外引起参考,否则这是没有问题的。

GnuCOBOL / OpenCOBOL没有通过下标/引用修改检查下标的使用或表的引用。如果你想考虑自己添加,你会非常欢迎。或者您可以将其作为功能请求发布。访问https://sourceforge.net/p/open-cobol/discussion/?source=navbar