如果使用另一个表的索引访问表元素(没有索引的表),它可能会在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
一般来说,交换独立表(不同大小)的索引似乎是错误的。
答案 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