× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.


  • Subject: Re: Procedure Problem
  • From: "Scott Klement" <infosys@xxxxxxxxxxxx>
  • Date: 24 Dec 1999 02:35:04 -0600

Jim Langston <jlangston@conexfreight.com> wrote:
>
> Now we get into something I think is not good.
>
> I abhor a function or subroutine to change the contents of a passed
>  variable.

I respectfully disagree with you.  Let me tell you my thoughts,
and what has worked the best in my experiences...

Lets say I created a sub-procedure that did something like this
         GetInventory(ItemNo: InvRec)
or for that matter, the simple read() or recv() sub-procedures
from sockets/IFS APIs...    They need to be able to both return
an error/success, and to return data.

Believe me, the best way to do this is to return the success/error
code, and load the data into one of the parms.  By returning the
success/error as its return value, you can easily use it in an
IF or DOW/DOU statement, like this:

            dow    read(file: data: %sizeof(data)) >= 0
         ... process each record in file
            enddo

If you return a data structure (which you can't convieniently
do in RPG... you'd have to return a character string, or a pointer
to a structure... both of which arent very slick) then you'd have
to do something like this:
            eval    data = read(file: %sizeof(data))
            move    data       datastruct
            dow     retcode >= 0
      ... process each record in file...
            eval    data = read(file: %sizeof(data))
            move    data       datastruct
            enddo

Seems pretty awkward to me.  (not to mention less efficient,
since you're copying all that data, rather than putting it
directly in the area of memory that you want it in)

So, thats why I feel that you SHOULD be allowwd to change a parm.
What I do think is important, however, is to properly use the
CONST and VALUE options on the parms to identify where a variable
is changed, and where it isnt...

Any time you don't have CONST or VALUE defined for a parameter,
you should EXPECT it to change, and take appropriate action by
passing a temporary copy of your variable...

>
> And yes, that is common too, but I think it is much worst than havin
> to pass another variable.
>
> As a user of a function, I have to be very aware that a function is
> changing one or more of my variables.  If I am not aware of this,
> I can trash trash my data very quickly.

Thats the whole point behind the CONST keyword!  To define your
sub-proc as one that can't change the data.   Sure, you can code
your routines to not change it anyway...   You can make it your
standard, and then assume that other people will always follow it,
so that your data isn't "trashed"...  but is that a good idea?

How do you know someone isn't going to change your service
program 2 years later?   How can you be SURE that the data isn't
going to be trashed?

>
> Consider a function that returns a value and changes a variable.  Su
> as something like (in pseudo C syntax)
>
> /* Function to return the length of a string without leading or
>  trailing spaces */
>
> int StringLength(char *SomeVar);
>
> Perhaps as a side effect this function modifies SomeVar in some way.
> Such as Trimming it to get the length without spaces.  If I am not
> aware of this I can do somethign like this:
>
> MyVar = '  SomeText';
> MyVarLen = StringLength(MyVar);
> Write(OutFile, MyVar);             /* Write the string to file */
> Write(OutFile, MyVarLen);       /* Write the TRIMed length to file *
>
> Now, not being aware that StringLength changed MyVar and made it
> 'SomeText'.  I now wrote 'SomeText8' or the such to the file (in my
> make believe Write statement).  I thought I wrote '  SomeText8'.

For this particular sub-proc, theres no logical reason to change
the actual string.  But, even if I wrote the routine, and KNOW that
it doesnt change the string, I still would never code it that way.

Why?  Because, again, someone could come along later and change it.
I could NEVER trust that StringLength routine to not change my
data!!

So, instead, when I wrote StringLength, I'd code it as:

int StringLength(const char *SomeVar);

Now I know that the variable won't be changed.  Likewise, a future
programmer will know that I didn't intend for that variable to be
changed, and he'll know that people may have made assumptions that
it won't be changed.

Since the procedure interface itself would have to change in order
to change the data in the string, he'd have to check every program
and make sure it'd work...

> And, yes, I have been bitten by this one before.  Very difficult bug
> to track down.

Yes, I've been burned too.   My response to this was to say "I'm
not going to trust another sub-proc that doesn't say CONST or VALUE
in its prototype to not change my data".

In many, many cases the ability to change the data in a parameter is
a very necessary and useful capability.  I'd hate to see programmers
throw that capability away, rather than learn the purposes of CONST
and VALUE and what can/can't be trusted.

Of course, this is just my opinion :)  I'm just hoping that this
message will be thought provoking to those readers on RPG400-L who
are new to procedure/function type programming, so they can decide
for themselves... :)

+---
| This is the RPG/400 Mailing List!
| To submit a new message, send your mail to RPG400-L@midrange.com.
| To subscribe to this list send email to RPG400-L-SUB@midrange.com.
| To unsubscribe from this list send email to RPG400-L-UNSUB@midrange.com.
| Questions should be directed to the list owner/operator: david@midrange.com
+---


As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.