Reputation: 4795
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
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
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
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.
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 RUN
or 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
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