Matt
Matt

Reputation: 4795

Multiple exit causing compiler warnings

I have a program where under several conditions I would want to exit early, rather than continuing through the flow, and rather than having to check for that exit-early condition in calling paragraphs.

To do this, I have a paragraph "EXIT-FAILURE", that checks to make sure that the general return flag field is not ok (0), logs a message (DISPLAY), and finally has the statement GOBACK.

However, doing this is giving me a compiler warning on every PERFORM that calls this "EXIT-FAILURE" paragraph: IGYCB7310-W The "PERFORM" statement at "PERFORM (line [line-number])" cannot reach its exit.

Is there any way to have this logic (which is basically multiple-exit/early-exit rather than single-exit), without having a compiler warning?

Is this idea entirely contrary to the COBOL way of doing things (my experience is more in Java, where this would be entirely normal in the context of guard statements or exceptions)?


EDIT: Adding minimal program requested by Simon:

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
   .

Results in these two warnings related to my question:

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.

(line 58.1 maps to the line "PERFORM A200-VALIDATE"; line 68.1 maps to the line "PERFORM Z900-EXIT-FAILURE")

Upvotes: 2

Views: 1680

Answers (4)

cschneid
cschneid

Reputation: 10775

My reaction to this compiler warning would be to add a comment in the source indicating that the warning is expected. IBM Enterprise COBOL 6.3 (the latest release as of this date) does not support the RAISE statement.

It's not unlike PERFORMing a paragraph that does an EXEC CICS RETURN.

@SimonSobisch knows more about COBOL than I ever will, and will hopefully supply an example of how to solve this more in keeping with the "COBOL way" which will be useful to future seekers of knowledge here.

Upvotes: 1

G. Barret
G. Barret

Reputation: 1

Using EXIT PARAGRAPH can help to avoid Go TO, compilation warnings, and comments ...

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"
   .

Upvotes: 0

FredTheFlinstone
FredTheFlinstone

Reputation: 41

Try the following:

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

As long as the compiler optimizer cannot determine the fact that the IF condition is always true, it won't raise the warning message.

A response to comment below and a few other suggestions...

Compiler optimization in some future release may determine the condition to be always true and remove it: This would cause the warning message to return. Face that problem when it occurs. For the present, something like: IF FUNCTION WHEN-COMPILED <= FUNCTION CURRENT-DATE will not be optimized away, and probably won't be for many years to come.

May produce less efficient code: The whole point of this paragraph is to exit the program. The extra instructions needed for the IF test should not have a measurable affect on performance.

Disable the diagnostic: This can be done using a compiler exit to catch and nullify the message, see: https://www.ibm.com/support/knowledgecenter/en/SS6SG3_6.3.0/pg/ref/rpext10.html . I would caution against this because valid warnings may also be suppressed, some of which probably should not be ignored.

Put a comment in the code indicating the warning is acceptable: Not all programmers are so diligent as to continue reviewing compiler warnings once they find out they are sometimes acceptable. Chances are good that valid warnings will be missed in the future.

Using DECLARATIVES: The IBM Enterprise COBOL compiler supports DECLARATIVES for I/O related errors and debugging only making their usage fairly restrictive. Furthermore, there are a number of additional restrictions as to whether a STOP RUNor GOBACK may be issued while a DECLARATIVE procedure is active. I would hesitate to advise using DECLARATIVES. Language Environment provides facilities to establish user defined condition handling but this is a fairly advanced topic. see: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.1.0/com.ibm.zos.v2r1.ceea800/ceea824.htm

Use GO TO Z900-EXIT-FAILURE: GO is recognized by the compiler as a go-there-and-don't-come-back transfer of control and will not issue message IGYCB7310-W provided the GO TO is conditionally executed (e.g. contained within an IF or other conditional statement). This is probably the best solution provided local coding standards permit usage of GO TO in these circumstances. Some places have an unjustified pathological fear of GO TO and won't allow it under any circumstances.

Upvotes: -1

Simon Sobisch
Simon Sobisch

Reputation: 7297

As seen in the compiler warning and the additional explanation from the compiler manual, the issue is that you PERFORM something and PERFORM says "do this and then come back".

If Enterprise COBOL for z/OS adds support for RAISE exception-name (and ideally user-defined exceptions) this would be the way to go (both being "COBOL" as requested in the question and "exceptional" like in java) and you'd place the paragraph into DECLARATIVES as EXIT-FAILURE SECTION. USE AFTER EXCEPTION CONDITION exception-name. Until then [= maybe forever]:

If there's no rule against this on-site: use GO TO EXIT-FAILURE - this COBOL verb says "go there" (and likely don't come back, especially with a well named paragraph as in your case).

If there's a rule against GO TO - go with the approach from @cschneid - add a comment in the header about this warning and reference this comment directly where it happens with another comment.

Side-note: I personally would still try to put the paragraph into DECLARATIVES (unchanged, as it is now, just move it "up" to DECLARATIVES) to stretch the point "this is only called if something goes wrong" even more. But your compiler may raise another warning or even error in this case (at least "standard"-COBOL requires a use-statement there).

Upvotes: 3

Related Questions