Problem Statement
This is, in a CALLed program, testing the address of a parameter being NULL to know how many parameters were passed on a particular CALL.
The technique is something that has worked in V4 and does not work in V5. Not only does it work in V4, but the technique has been used in various places over a number of years.
Initial Answer
No, you can't do that, the behaviour is undefined
I provided a sample program of my own, which happily fell over with a S0C4 (and also had access to an address for the second parameter from the previous CALL)
Investigation
A minimal sample working program was obtained. It failed when I ran it.
I usually investigate with NOOPT, so I tried with OPT. The provided sample program worked.
Compiled mine with OPT. Still refused to work.
Reviewed working program. It used CALL indentifier, which would be a dynamic CALL. Mine used CALL literal with compiler option DYNAM. The generated code had dissimilarities.
Changed mine to use CALL identifier, and it ran without a S0C4.
When does it work?
There are generally three ways a COBOL program can be CALLed by another COBOL program:
CALL literal, compile NODYNAM
CALL literal, compile DYNAM
CALL identifier, generates code for dynamic CALL not matter the compile option
In V4 you can have the optimizer on (OPT(STD) or OPT(FULL), no difference to the generated code) or off (NOOPT). That gives six combinations. Of those six combinations, only one, CALL identifier with OPT(STD) (or FULL), works.
And it doesn't always work. My sample program, when it ceased to fall over, simply gave access to the previous parameters.
The working example program, which had more code than just CALL statements in my example, didn't work if the second and third CALLs, with two and three parameters, were commented out, leaving just a CALL with one parameter. That gets a S0C4.
Conclusion
With V4 the technique "works" with a subset of CALL/OPT combinations, the one used at the site in question.
It only works in a subset of cases, due to the relationship of optimized code to the issue. It would seem that the larger the program doing the CALL, the more likely the technique in the CALLed program will work. However, I'd not like to have that as the epitaph for a 2am problem.
Recommendation
Use a reliable technique to identify the last parameter passed to a COBOL program via CALL. This can be done in Assembler with a short walk back up the search-chain and looking for, from the right, the high-order bit of the address of the parameter.
I've left that technical. For readers who don't understand that, forget about doing it yourselves.
To my mind, it is good never to attempt to access data which was not included on the current CALL, and that includes the address of the data, because it may not be the address: it may be invalid (S0C4); or a valid address, but the address of a different piece of data.
BillWoodger