Hi Charles,
<snip>
It's pretty simple really, the key thing to realize is that in both cases
not only are you passing the
data in the variable but you're passing the current length of the variable
also.
</snip>
I understand that part. But I'm wondering more about the actual mechanics of
passing a varying string by value.
For example, if I have a PI for a 2500A varying parameter and the caller
passes a 32000A varying variable (containing the string 'ABC') I now know
this process will involve two data copies. What I would like to know is
whether both only copy 3 bytes. I would also like to know how the copies are
performed for a standard alpha parameter/variable pair. Would both copies
involve copying 2500 bytes or would the first low-level copy try to copy the
full 32000 bytes only to later get truncated. I think Barbara said both
would truncate for the non-varying character. I'm hoping both would only
copy 3 bytes too for the varying character. But I do wonder if the first
copy would still reserve 32000 bytes for the field only to copy 3 bytes into
it.
<snip>
With, *VARSIZE, you have to pass the length explicitly in another parameter.
</snip>
I don't usually code my prototypes that way. If I am going to cater for all
kinds of large character variables then I would not rely on the caller to
pass the correct length. I would use opdesc and CEEDOD and get the actual
length passed. Of course I now know I can't always rely on that either. :-)
<snip>
With VARYING, the length is implicitly defined as the first two bytes of the
variable.
</snip>
Yep, or at least until we go to V6R1. :-)
<snip>
Now consider a procedure that takes a 2500a CONST VARYING parm.
You pass a 100a VARYING variable to it, which at run time only contains 50
characters.
Inside the procedure is a 2500a VARYING work field.
if you have an eval WRKFLD = PARM1, at run time, the procedure knows PARM1
only has 50 chars, so the
procedure only accesses the first 50 characters.
if you're dealing with *VARSIZE instead, the code in the procedure instead
has to look like
eval WRKFLD = %subst(PARM1:1:PARM2)
where PARM2 contains the length of PARM1.
Works the same way if you pass a literal, except a temporary variable is
created during compile to
hold the data. But the temporary variable need not be 2500a, instead it only
needs to be big enough
to hold the literal.
</snip>
This all makes sense.
<snip>
AFAIK, passing a VARYING by value is always going to result in a temporary
variable (onto the stack?)
of the same max length as the procedure parameter.
</snip>
It is this process which most intrigues me at the moment. As I now know call
by value has this extra low-level overhead I want to know how much of an
extra overhead it really is. Also, when we go to V6R1 will passing a varying
character with a 2-byte length prefix need to be upcast to another variable
if the prototype defines a new megachar with a 4-byte length prefix?
<snip>
If you're dealing with large strings,
1) Use VARYING
2) pass by CONST reference
Passing by value makes sense for small fields, 1-16 bytes, larger than that
and CONST is a better
choice.
</snip>
Yep, This makes sense to me too.
<snip>
Here's a related thread from last year (that you participated in BTW ;-)
http://archive.midrange.com/rpg400-l/200605/msg00162.html
</snip>
Hee hee. I have a memory like a goldfish... :-)
But my point is really concentrated on the overhead not mentioned in the
manuals. We 'know' const is more efficient than value and we 'know' varying
is more efficient than non-varying but it all seems a little anecdotal.
Strange when we work in a real of picosecond precision. ;-)
I mean, when you sit down and explain to somebody WHY in some situations
using const is much more efficient than value you find it difficult when
you're not really sure why yourself. You just 'know' it is better, and that
just doesn't sound too great as an explanation. At least I now have a better
understanding of the WHY part. It will help me sleep at night. :-)
Cheers
Larry
As an Amazon Associate we earn from qualifying purchases.