On 1/27/2014 8:29 AM, Briggs, Trevor (TBriggs2) wrote:
... I suppose if
there were a limited number of acceptable values for the parameter that
you could check against then the chances of "accidentally" finding ones
of these in a "phantom" parameter would be negligible. But in cases
where the parameter values could be a large number of values it seems
from this thread that IBM gives us NO 100% reliable way of determining
the number of parameters passed to a CL program. Is that so?
About checking for a valid set of values, if it's possible that the 
procedure could be called with all the parameters once, and then a bit 
later with fewer parameters, the parameter from the first call could be 
the one that is found in the second call, so you could still get a false 
positive using that technique.
There is nothing in the documentation to suggest that CL supports 
optional (unpassed) parameters.
As Chuck said, 'The documentation is clear enough... and that is, that 
results are *unpredictable* with regard to the lack of specification of 
parameters for a CLLE; i.e. optional parameters.'
Here's the documentation that Chuck is referring to.
http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Frbam6%2Fpassp.htm
Rule to live by 1: Safety first.
Rule to live by 2: Never take advantage of undocumented features.
If I wanted to change a CL procedure so that it had a new optional 
parameter, I'd rename the CL procedure, and use the old name for an RPG 
wrapper procedure. The RPG procedure could either pass a default value 
for the new parameter, or it could pass *OMIT.
  Old CL procedure MYPROC: PARM(&P1 &P2)
  New CL procedure MYPROC_3: PARM(&P1 &P2 &P3)
  New RPG procedure MYPROC: P3 has OPTIONS(*OMIT)
  RPG procedure MYPROC:
    1) passing *OMIT explicitly
        if %parms() < %parmnum(P3); // p3 not passed
           MYPROC_3 (p1 : p2 : *OMIT);
        else;
           MYPROC_3 (p1 : p2 : p3);
        endif;
    2) ensuring that the address of p3 is null
        D p3_parm      s       based(p_p3_parm)
        D p_p3_parm    s    *  inz(*null)
          if %parms() >= %parmnum(p3);
               p_p3_parm = %addr(p3);
          endif;
          MYPROC_3 (p1 : p2 : p3_parm);
    3) passing a default value for p3
        D p3_parm      s        inz(default value)
          if %parms() >= %parmnum(p3);
               p3_parm = p3;
          endif;
          MYPROC_3 (p1 : p2 : p3_parm);
Always bearing in mind that %PARMS is unreliable if the caller does not 
pass at least a minimal operational descriptor. RPG and CL always do; C 
and COBOL can be coded so they do; SQL procedure calls never do; the 
call-procedure API never does.
As an Amazon Associate we earn from qualifying purchases.