Scott,
I'm focused on the documentation (could be improved?) and maybe I've missed something somewhere in the docs. I'm not arguing with the complier writer that it won't work reliably. I didn't reply to her reply and am grateful for the reply. Here was my own test program based on the original question from Lim:
H DEBUG
D proc1 pr
D parm1 10p 0
D parm2 10 options(*nopass :*omit) const
D parm3 10 options(*nopass :*omit) const
D proc2 pr
D parm1 10
D parm2 10 options(*nopass :*omit) const
D parm3 10 options(*nopass :*omit) const
D ParmP S 10P 0 Inz( 0 )
/Free
proc1( parmP );
proc1( parmP : *OMIT );
proc1( parmP : *OMIT : *OMIT );
*InLR = *On;
Return;
/End-Free
P proc1 B
D proc1 pi
D parm1 10p 0
D parm2 10 options(*nopass :*omit) const
D parm3 10 options(*nopass :*omit) const
D Parms S 5P 0
D ParmA S 10A
D NullParm1 S N
D NullParm2 S N
D NullParm3 S N
/Free
Parms = %Parms();
NullParm1 = ( *Null = %Addr( parm1 ) );
NullParm2 = ( *Null = %Addr( parm2 ) );
NullParm3 = ( *Null = %Addr( parm3 ) );
Dump;
proc2( ParmA : parm2 : parm3 );
Return;
/End-Free
P proc1 E
P proc2 B
D proc2 pi
D parm1 10A
D parm2 10 options(*nopass :*omit) const
D parm3 10 options(*nopass :*omit) const
D Parms S 5P 0
D NullParm1 S N
D NullParm2 S N
D NullParm3 S N
/Free
Parms = %Parms();
NullParm1 = ( *Null = %Addr( parm1 ) );
NullParm2 = ( *Null = %Addr( parm2 ) );
NullParm3 = ( *Null = %Addr( parm3 ) );
Dump;
Return;
/End-Free
P proc2 E
(I'm a bit old school with dump)
NullParmX is getting set the same in proc2 for all three calls with and without *OMIT. I should have tested a call without the parm after a call with the parm and tested for calls with real parms as well as *OMIT as you just demonstrated.
Thanks,
Paul Morgan
Principal Programmer Analyst
IT Supply Chain/Replenishment
-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx [mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Scott Klement
Sent: Wednesday, March 09, 2011 2:01 PM
To: RPG programming on the IBM i / System i
Subject: Re: Calling similiar (overloaded) procedure that has *nopass *omitin the parameter
hi Paul,
Here's a program that should demonstrate the problem. Not sure why
you're arguing the point (do you really think you know more about this
than the lead developer of the RPG compiler?!) but I've known about this
for QUITE a long time (longer even than ILE has existed) and I can vouch
for her.
But, anyway... try this program, you will (most likely) see the problem:
H DFTACTGRP(*NO)
D myProc PR
D parm1 10a
D parm2 10a options(*nopass)
D one s 10a inz('blah')
D two s 10a inz('blah')
/free
// For this call, %ADDR() will PROBABLY (but not guaranteed)
// work, because nothing in the parm stack has been used yet.
myProc(one);
// This call passes both parameters, so will work.
myProc(one: two);
// This call will PROBABLY (but not guaranteed) show that
// only one parm was passed, but %addr(parm2) won't be null.
myProc(one);
return;
/end-free
P myProc B
D PI
D parm1 10a
D parm2 10a options(*nopass)
D count s 10i 0
D msg s 52a
/free
count = %parms();
msg = 'You passed ' + %char(count) + ' parms.';
dsply msg;
if %addr(parm1) = *null;
dsply ('parm1 = *NULL');
else;
dsply ('parm1 <> *NULL');
endif;
if %addr(parm2) = *null;
dsply ('parm2 = *NULL');
else;
dsply ('parm2 <> *NULL');
endif;
/end-free
P E
When I call this, I get:
CALL MYPGM
DSPLY You passed 1 parms.
DSPLY parm1 <> *NULL
DSPLY parm2 = *NULL
DSPLY You passed 2 parms.
DSPLY parm1 <> *NULL
DSPLY parm2 <> *NULL
DSPLY You passed 1 parms.
DSPLY parm1 <> *NULL
DSPLY parm2 <> *NULL
Note that on the final call, it says you've passed only 1 parameter
(which makes sense, since that's what the code does) but parm2<>*NULL.
On 3/9/2011 8:28 AM, Morgan, Paul wrote:
I'm curious where in the V5R4 documentation it mentions that using %addr() on a *NOPASS parameter is unreliable? With my testing on program subprocedures it works. Maybe with further testing it won't. Maybe it won't work with a service program procedure. The RPG documentation (reference and user guide) talks about using %addr() on an *OMIT parameter but no mention of results on a *NOPASS parameter.
Paul Morgan
Principal Programmer Analyst
IT Supply Chain/Replenishment
-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx [mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of John McKay
Sent: Wednesday, March 09, 2011 1:35 AM
To: RPG programming on the IBM i / System i
Subject: Re: Calling similiar (overloaded) procedure that has*nopass *omitinthe parameter
Barbara,
Lucky programmers document and test, test and document. They also
read the documentation and the code.
Regards,
John McKay mba
On 08/03/2011 23:00, Barbara Morris wrote:
On 2011/3/8 3:18 PM, Morgan, Paul wrote:
Have you tried to check the address of a *nopass parameter if it
wasn't passed? I get *NULL when I check in my test program and the
program doesn't break.
You've been unlucky then. If you were lucky, you would have seen a
non-null pointer that just happened to be lying around where your
program was looking for it, and your program would have broken because
it thought the parameter had actually been passed.
Sometimes programs and procedures that access unpassed parameters can
work for years, and then something changes about what happens before the
program or procedure gets called, and *boom*, you get an error.
Everything might seem to work fine until you demo it to your boss, or
until just after it goes into production, or until just before you go on
vacation, or ...
As an Amazon Associate we earn from qualifying purchases.