On 27-Jun-2014 15:47 -0500, rick baird wrote:
I have a very simple program I can call from a CLP that just
retrieves and returns a value based on the value passed - use
example:
CALL PGM(SU22A1) PARM('FROMVERS3 ' &OLDVERS )
CALL PGM(SU22A1) PARM('OBJLIB ' &NJOBDL )
CALL PGM(SU22A1) PARM('JOBD ' &NJOBD )
From the utilization shown, the program SU22A1 could possibly be
better coded as a /retrieve-command/ invocation, with a parameter for
each of the various passed-values. As a side effect of that
implementation, the problem would likely be avoided, because the design
of the called program as a CPP for a retrieve command would necessarily
have a separate parameter for each return-value.
I use the different variables in commands thereafter. As I step
through each step in debug, after the first call, the variable
&OLDVERS has the value I expect. After the second call, variable
&NJOBDL has the value I expect, but &OLDVERS is now blank, and after
the third call, &NJOBD has the value I expect, but &NJOBDL is blank
too.
What gives? I'm guessing it's an issue with the called program
reusing the same pointer space in memory,
The memory\storage utilized is a distinct address for each CLP
variable passed on the separate invocations; the 2nd argument of the
/called program/ refers to distinct by-address location that was passed
[i.e. passed by reference] from the CLP on each invocation. The three
CL variables are likely to be in the same /contiguous/ memory however,
yet obviously, they can not be at the /same/ location. Likely the CL
variables are in the /same/ vicinity within the /automatic storage/,
each at an offset that is incrementally a number of bytes beyond the
previous variable; a number that is equivalent to the declared length
the previous variable.
but how can I keep this from happening short of saving off the value
before calling the next one?
The method that Booth showed
<
http://archive.midrange.com/rpg400-l/201406/msg00154.html> is probably
the simplest and safest solution, if the changes should be confined to
the CLP. In that case, the one CL variable used repeatedly for the 2nd
argument would be declared to match the declaration for the 2nd
parameter in the program SU22A1. However the Change Variable (CHGVAR)
after each invocation may not qualify as avoiding "saving off the value
before calling the" program SU22A1 the next time.
Probably the program SU22A1 has declared the 2nd parameter as a
character variable with a /long/ length that can accommodate
generically, any "value returned" for each of the possible "value
passed" literals. That program also probably does a simple assignment
to that character [string] variable, for which the effect is
blank-padded result. The blank padding for the /long/ length presumably
is overwriting the contiguous storage that is utilized for the other CL
variables. That is, I suspect the called program SU22A1 does something
like the following pseudo-code:
dcl &value_passed *char 10
dcl &value_returned *char 200 /* largest possible rtn value */
case &value_passed
when 'FROMVERS3 '
then &value_returned=&fromver
when 'OBJLIB '
then &value_returned=&objlib
...
The problem described would occur in the calling program because
although the calling program passes only a 10-byte variable for the
"object library" variable named &objlib, the 190 bytes beyond those
first ten bytes would be /cleared/ [set to blanks] as the side effect of
the padding for the simple assignment of the variable named &value_returned.
Given the program SU22A1 already must be coded with the /assumption/
that the caller will provide the proper storage for the respective
literal value [passed as the 1st argument], then a simple resolution can
be confined to the called program; keeping that same /assumption/
however. That called program would be modified to ensure that each
assignment is made to a substring of the passed storage, rather than an
assignment of the declared character [string] variable itself. In
pseudo-code:
case &value_passed
when 'FROMVERS3 '
then %sst(&value_returned:&fromverLen)=&fromver
when 'OBJLIB '
then %sst(&value_returned:&objlibLen)=&objlib
...
That resolution is not very desirable because the assumptions are not
removed from the called program.
As an Amazon Associate we earn from qualifying purchases.