× 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.



Thank you all for your answers. I think I understand the issues now.

-----Original Message-----
From: rpg400-l-bounces@xxxxxxxxxxxx
[mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Scott Klement
Sent: Tuesday, February 05, 2008 11:37 AM
To: RPG programming on the AS400 / iSeries
Subject: Re: Subprocedure scoping?

Hi Kim,

"type_ds" is a variable that's internal to a subprocedure. That means
that your program requests memory for type_ds when the procedure starts,
and tells i5/OS that it can have the memory back (for re-use) when the
procedure ends.

Since you use pointers to refer to the data after the procedure has
ended, it'll be a matter of luck as to whether i5/OS has re-used the
memory for something else, or not. If it has, you'll get "garbage" in
it. (It's not really garbage, the memory is just being used for
something else, so it has values you didn't expect.) If you change it,
then whatever else is using the memory (most likely, one of your other
procedures) will see "garbage" in some of it's variables, because it's
not expecting you to overwrite the data with something else.

The quick-fix, band-aid for this is to code "static" on the D-spec for
the "type_ds" data structure. The keyword "static" means that the
memory is NOT released when the procedure ends, instead it's retained
until the activation group ends. It also means that any INZ statements
are only carried out once -- when the subprocedure is called the first
time -- and not re-run each time the procedure is called. The static DS
will retain it's values between calls to the procedure.

However, frankly, this is not a good way to write code. What you SHOULD
do is:

a) Eliminate the pointer logic.
b) Eliminate the fact that the format of the data structure is defined
in multiple places (which is error prone, and maintenance heavy)
c) Have a higher-level caller be responsible for the memory instead of
the subprocedure, which makes it more re-usable. (If you have multiple
callers, they don't overwrite each other's values.)

These things may sound a little complex, but really they're not.. not at
all... Just pass the data structure as a PARAMETER (without CONST or
VALUE) instead of returning a pointer. Declare your parameters and
variables using LIKEDS so that the format of the DS only needs to be
declared once. It's easy.



Kim Spears wrote:
To fellow ILEers

I'm trying to use a pointer to a data structure to pass data back from

a sub procedure. I had it working at one point but have since made
some changes and now it doesn't work. What's happening is $obcGetType

loads the data structure properly and the pointer is getting passed
back to $obcSelect, however the data in the 'type' data structure in
$obSelect is garbage. It's almost like once $obcGetType goes out of
scope the memory for type_ds gets corrupted. Any suggestions?

D $obcGetType PR *
D obcFile 10 CONST
D obcField 10 CONST
****************************************************************
* $obcSelect - Prompt for valid one-byte codes for a specified
* field in a specific file
*--------------------------------------------------------------*
P $obcSelect B EXPORT
D $obcSelect PI 1
D obcFile 10 CONST
D obcField 10 CONST

D p_type S *
D type DS BASED(p_type) Qualified
D ID 10I 0
D Description 50A
*--------------------------------------------------------------*
C EVAL p_type = $obcGetType(obcFile :
obcField)
.
.
.
C RETURN oneByteCode
*--------------------------------------------------------------*
P $obcSelect E
****************************************************************
* $obcGetType - Given a file and field return the type
*--------------------------------------------------------------*
P $obcGetType B
D $obcGetType PI *
D obcFile 10 CONST
D obcField 10 CONST

D p_type S *
D type S BASED(P_TYPE) LIKE(type_ds)

D type_ds DS Qualified
D ID 10I 0
D Descrptn 50A
*--------------------------------------------------------------*
/FREE

OPEN DOOBCTYP01;
CHAIN (obcFile:obcField) DOOBCTYP01;
IF %FOUND(DOOBCTYP01);
EVAL type_ds.ID = otID;
EVAL type_ds.Descrptn = otDescrptn;
EVAL p_type = %ADDR(type_ds);
ELSE;
EVAL p_type = *NULL;
ENDIF;
CLOSE DOOBCTYP01;
RETURN p_type;

/END-FREE
*--------------------------------------------------------------*
P $obcGetType E


--
This is the RPG programming on the AS400 / iSeries (RPG400-L) mailing
list To post a message email: RPG400-L@xxxxxxxxxxxx To subscribe,
unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives at
http://archive.midrange.com/rpg400-l.


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

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.