多次退出导致编译器警告

Multiple exit causing compiler warnings

我有一个程序,在某些情况下我想提前退出,而不是继续整个流程,也不必在调用段落时检查提前退出的条件。

为此,我有一段 "EXIT-FAILURE",检查以确保一般 return 标志字段不正确 (0),记录一条消息 (DISPLAY ), 最后有语句 GOBACK.

但是,这样做会在调用此 "EXIT-FAILURE" 段落的每个 PERFORM 上向我发出编译器警告: IGYCB7310-W The "PERFORM" statement at "PERFORM (line [line-number])" cannot reach its exit.

有没有什么方法可以在没有编译器警告的情况下实现这种逻辑(基本上是 multiple-exit/early-exit 而不是单退出)?

这个想法是否与 COBOL 的做事方式完全相反(我的经验更多的是 Java,在 guard 语句或异常的上下文中这将是完全正常的)?


编辑:添加西蒙要求的最小程序:

IDENTIFICATION DIVISION.
PROGRAM-ID. SOQUEST.
ENVIRONMENT DIVISION.
DATA DIVISION.
PROCEDURE DIVISION.
   PERFORM A100-INITIALIZE
   PERFORM A200-VALIDATE

   PERFORM B200-PROCESS-STEP-1

   GOBACK
   .
A100-INITIALIZE.
   DISPLAY "INITIALIZED"
   .
A200-VALIDATE.
   PERFORM Z900-EXIT-FAILURE
   .
B200-PROCESS-STEP-1.
   DISPLAY "COMPLETED STEP 1"
   .
Z900-EXIT-FAILURE.
   GOBACK
   .

与我的问题相关的这两个警告的结果:

IGYCB7310-W   The "PERFORM" statement at "PERFORM (line 58.1)" cannot reach its exit.
IGYCB7310-W   The "PERFORM" statement at "PERFORM (line 68.1)" cannot reach its exit.

(第 58.1 行映射到第 "PERFORM A200-VALIDATE" 行;第 68.1 行映射到第 "PERFORM Z900-EXIT-FAILURE" 行)

我对 this compiler warning 的反应是在源代码中添加一条注释,表明警告是预期的。 IBM Enterprise COBOL 6.3(截至该日期的最新版本)不支持 RAISE 语句。

这与执行 EXEC CICS 的 PERFORMing 段落没有什么不同 RETURN。

@SimonSobisch 对 COBOL 的了解比我以往任何时候都多,并希望提供一个示例,说明如何更符合“COBOL 方式”,这将对未来的知识寻求者有用。

如编译器警告和编译器手册中的附加说明所示,问题是您 PERFORM 某些东西并且 PERFORM 说 "do this and then come back"。

如果 z/OS 的企业 COBOL 添加了对 RAISE exception-name 的支持(理想情况下 user-defined 例外),这将是可行的方法(两者都是 "COBOL"问题和 "exceptional" 就像在 java) 中一样,您会将段落放入 DECLARATIVES 中作为 EXIT-FAILURE SECTION. USE AFTER EXCEPTION CONDITION exception-name。在那之前[=也许永远]:

如果没有规则反对这个 on-site:使用 GO TO EXIT-FAILURE - 这个 COBOL 动词说 "go there"(并且可能不会回来,特别是在一个命名良好的段落中你的情况)。

如果有反对 GO TO 的规则 - 使用 @cschneid 的方法 - 在 header 中添加关于此警告的评论,并在与其他评论一起出现的地方直接引用此评论。

Side-note:我个人仍会尝试将段落放入DECLARATIVES(不变,因为现在,只需将其 "up" 移动到 DECLARATIVES) 即可进一步拉伸点 "this is only called if something goes wrong"。但是在这种情况下,您的编译器可能会发出另一个警告甚至错误(至少 "standard"-COBOL 在那里需要 use-statement)。

尝试以下操作:

Z900-EXIT-FAILURE.
    IF <some condition that is always true>
        GOBACK
    END-IF
    .

只要编译器优化器无法确定 IF 条件始终为真,就不会引发警告消息。

对下面评论的回应和其他一些建议...

编译器在未来某个版本中的优化可能会确定条件始终为真并将其删除: 这将导致警告消息 return。当它发生时面对那个问题。目前, 类似于:IF FUNCTION WHEN-COMPILED <= FUNCTION CURRENT-DATE 不会被优化掉,而且可能在未来很多年都不会。

可能会产生效率较低的代码: 这一段的重点是退出程序。这 IF 测试所需的额外说明不应具有可衡量的影响 关于性能。

禁用诊断: 这可以使用编译器出口来捕获和 使消息无效,请参阅:https://www.ibm.com/support/knowledgecenter/en/SS6SG3_6.3.0/pg/ref/rpext10.html。 我会警告不要这样做,因为有效的警告也可能被抑制,其中一些 可能不应该被忽视。

在代码中添加注释以表明警告是可以接受的: 并不是所有的程序员都勤奋到继续检查编译器警告一次 他们发现他们有时是可以接受的。很有可能会错过有效的警告 将来。

使用声明: IBM Enterprise COBOL 编译器支持 DECLARATIVES for I/O 相关错误 和调试只会使它们的使用受到相当的限制。此外,对于是否 STOP RUNGOBACK 还有一些额外的限制 可以在声明程序处于活动状态时发布。我会犹豫建议使用 DECLARATIVES。 语言环境提供便利 建立用户定义的条件处理,但这是一个相当高级的主题。 参见:https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.1.0/com.ibm.zos.v2r1.ceea800/ceea824.htm

使用GO TO Z900-EXIT-FAILURE: GO 被编译器识别为去那里不回来的控制权转移 如果 GO TO 是有条件的,则不会发出消息 IGYCB7310-W 已执行(例如包含在 IF 或其他条件语句中)。这可能是提供的最佳解决方案 本地编码标准允许 在这些情况下使用 GO TO。有些地方对 GO TO 有一种不合理的病态恐惧 并且在任何情况下都不允许。

使用 EXIT PARAGRAPH 可以帮助避免 Go TO、编译警告和注释...

IDENTIFICATION DIVISION.
PROGRAM-ID. SOQUEST.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01  FLAGS.
    03  WS-VALIDATION           PIC 9 VALUE ZERO.
     88 WS-VALIDATION-OK        VALUE 0.
     88 WS-VALIDATION-ERROR     VALUE 1.

PROCEDURE DIVISION.
MAIN.
    PERFORM A100-INITIALIZE

    PERFORM A200-VALIDATE
    IF WS-VALIDATION-ERROR
        EXIT PARAGRAPH
    END-IF

    PERFORM B200-PROCESS-STEP-1
    .
CLOSE-FILES.
    CLOSE XXXX
    CLOSE YYY
    .
EXIT-PROGRAM.
    GOBACK
    .
A100-INITIALIZE.
    DISPLAY "INITIALIZED"
    .
A200-VALIDATE.
* Do next when validation fails ...
    MOVE 1 TO WS-VALIDATION

    ANY-VALIDATION-HERE
    IF ERROR-FOUND  
        EXIT PARAGRAPH
    END-IF

    CONTINUE-WITH-OTHER-VALIDATIONS
    IF ERROR-FOUND
        EXIT PARAGRAPH
    END-IF

* Arriving here .. MEANS VALIDATION IS ok
    MOVE O TO WS-VALIDATION
   .
B200-PROCESS-STEP-1.
   DISPLAY "COMPLETED STEP 1"
   .