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



Scott,
 
I'm with you on this one.  You've described a technique that I've used a lot, 
and found to be very practical.
 
Consider the example of a service program that exports a set of procedures for 
managing linked lists, which some folks call dynamic arrays.  One procedure 
could instantiate a new list, and return a pointer to that "instance".
 
The instance pointer could be passed to other procedures used to add or remove 
entries in the list.  The list "instance" is a reference to a dynamically 
allocated data structure, having sub-variables that specify the number of 
entries in the list, the pointer to the first entry in the list, and so forth.
 
Sure, it would be possible to return a numeric value that provided a reference 
to an index, which provided a reference to an "instance", but returning the 
"instance" pointer is a simpler solution.
 
Nathan M. Andelin


Scott Klement <rpg400-l@xxxxxxxxxxxxxxxx> wrote:Hi Alan,

> Returning pointers from a service program or external routine is 
> extremely bad form no matter what. The only time that I find it 
> appropriate is where it must be returned as with a 
> USPC_GetPointerToUserSpace.

I agree with you that you should not return pointers in situations where 
the calling routine is expected to interpret the contents of the memory 
that it points to.

However, by the same token, I don't think returning a pointer to a user 
space is a good idea, either!! The calling program shouldn't need to know 
that you've stored your data in a user space, or dynamic memory, or a 
file, or anything else -- all of that should be transparent to the caller! 
Returning a pointer to a user space is every bit as bad as returning a 
pointer to allocated memory or to a static variable.

Unfortunately, in the case of MODS, there's no other way to pass them from 
one procedure to another. So, if you MUST pass a MODS, that's how you have 
to do it. Though, I agree that replacing the MODS with multiple calls to 
a procedure is better, if it's possible.

The one place that I do allow returning a pointer is when the pointer is 
"opaque". In other words, the caller doesn't need to know what it points 
to, what the format of that space is, how big it is... it doesn't have to 
know anything about it. Although I know that some people on this list 
won't agree with me, I don't think an opaque pointer is that bad. It's 
certainly better than returning a data structure (which is the workaround 
that I've seen many people do)

For example, let's say you're creating a service program that works with 
an order. You want to use a pseudo-object-oriented approach. So you do 
something like this:

x = order_new();
order_load(x: 'SA12354');
order_setShipTo(x: 'Scott Klement'
: '123 Sesame St'
: 'Milwaukee'
: 'WI'
: '53201' );
order_save(x);
order_destroy(x);

In the code above, X is a pointer. The "ORDER" service program contains 
subprocedures called "order_new" "order_load" "order_setShipTo", etc. 
Inside that service program, it points to a data structure that contains 
all of the per-order state information. That way, the srvpgm can be 
written to allow many different "order objects" to be created at once.

To encapsulate this, order_new() allocates space for the DS, and returns 
the pointer. The caller doesn't know what the format of the memory, the 
size of the allocatation, etc are. All it knows is that this is a "handle" 
that it has to pass back to the other routines in the order srvpgm. 
Obviously, order_destroy() frees up that memory.

That way, if I need to add more stuff to the ORDER srvpgm's data 
structure, I can make the allocation bigger, add fields, etc, without 
breaking anything.

I consider this approach to be acceptible. Now, I know someone is going 
to reply to this message and tell me that I should use a numeric handle 
instead of a pointer. And, I don't disagree, but I don't think the 
pointer method is bad, either. If someone is foolish enough to examine 
the memory that the pointer points to and try to reverse engineer the data 
structure, they deserve their fate when an upgrade breaks compatibility :)

But, for sure, in a situation like yours where people are returning a 
pointer and expecting the caller to interpret the memory, I think that's a 
bad idea, and should be nipped in the bud.

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.