|
That's more detail than I might go into, but it sure covers the subject nicely. Passing by reference is usually preferable to using pointers. It does a lot of the same things, but is easier to understand and less error prone. The reason C uses pointers heavily is that it doesn't support passing by reference. There's a baseball gag about an 80s player named John Kruk. He looked like someone you might see at the supermarket buying two twelve packs of beer, a carton of cigarettes, and a bunch of junk food. Supposedly someone asked him if smoking was bad for his career as an athlete. Kruk replied "I'm not an athlete, I'm a ballplayer." I'm not a programmer, I'm an RPG programmer. For what I do I'm happy to have the wealth of high level stuff that's available to me so I can concentrate on the business side. If I never have to decipher a pointer to a pointer to a pointer I don't care. It's nice to have some of the lower level things available, but they're not necessary to do a lot of the things I do. It's helpful to understand them so you can make intelligent decisions about when and when not to use them. Sometimes you really do need them. > -----Original Message----- > From: rpg400-l-bounces+jfritz=sharperimage.com@xxxxxxxxxxxx > [mailto:rpg400-l-bounces+jfritz=sharperimage.com@xxxxxxxxxxxx] > On Behalf Of Alan Campin > Sent: Tuesday, July 05, 2005 10:32 AM > To: rpg400-l@xxxxxxxxxxxx > Subject: RE: Multi Occurrence Data Structure returned from a procedure > > >> Passing a pointer as a "both" parameter (meaning both input and > >>output) will work fine. However, don't RETURN a pointer > unless you understand the ramifications of doing so, and have > taken appropriate precautions. > > 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 am, also, opposed to passing pointers to service programs. > It is just too dangerous a practice as the receiving program > has no idea what the hell it is receiving. Could be a pointer > to anything and I have found little reason to do so. Passing > a variable by reference does the same thing except the > operating system is making sure what you pass is valid. > > The following is a write-up I did for your office on > returning pointers and the problems I see with them. This is > kind of long. Sorry. > > ============================================================== > ====================================================== > > Recently it has come to my attention that we have been > returning pointers in RPG/ILE from service programs to return > multiple records. I am not only concerned because this as > happened in the past but we are talking about creating > further service programs doing this. > > I have a series of objections to the practice and feel it is > very poor programming practice to return a pointer from a > service program. > > The only exception to that rule that I know of is a service > program that returns a pointer to a user space. > > I have been writing service programs for eight years and many > times have been faced with returning multiple records to > caller. Many times I have considered using pointers but have > always rejected them for the reasons I state below. I have > never found a need to use a pointer in order to get multiple > records or information from a service program. > > My concerns are on several levels. > > Number 1 - Violation of Software Engineering Principals > > Returning a pointer to a user program violates the number one > rule of Software Engineering, Encapsulation or Information > Hiding as you might want to call it. > > You never expose details of how a function is implemented to > the user of a service. The internal implementation of a list > of items might be a fixed array, a dynamic array, a linked > list, a pointer to a user space or even a cursor from an SQL > statement. > > Returning a pointer says how you have implemented the > function. The number one problem is doing this is you are now > restricted if you want to change the function. If you > suddenly realize in the future that you need to re-implement > using a linked list or even an SQL cursor, you are out of > luck because a linked list or cursor requires program logic > to read through a list. > > Having exposed the internals, you cannot change the internal > data structures. If you touch the internal data structures, > you break any program using it because anyone using the > pointer is basing their processing on pointer math either > directly or through a pointer to a multiple occurrence data > structure and there is no way for the user of the function to > know that the internal structures have changed. You will have > to go back and redevelop every program that uses that service > program. If you miss one, you have a real mess. > > In addition, you are violating the most basic rules > concerning implementation of a procedure or function. > > A procedure or function should perform one function and only > one function and you should be able to describe what the > function does without the use of conjunctive verbs like AND > or OR. There should be a known set of inputs and a known set > of outputs > > In other words, functional decomposition. Breaking the > problem down into smaller and smaller pieces until each piece > is responsible for doing one thing. > > If a function returns a pointer, you are saying something > like GetListofStylesAndReturnList instead of something like > BuildStyleList and GetStyleRecord. > > Number 2 - The consumer of the service must implement the logic. > > Hardly less important is the fact that the user of the > service program must implement the logic to retrieve the data > instead of the programmer who wrote the service program. > > Pointers in the wrong hands can be very dangerous. The person > using the pointer can do just about anything he or she wants > to do with it. Making a mistake in implementation means > walking all over memory in the service program. Results are > completely unknown and there is no way to error check to see > if what they are doing is correct. It is a simple hope and by > god kind of thing. > > Under no circumstances should a consumer of a service have to > implement the product that he or she is using but that is > what we are asking the programmer to do. Instead of simply > calling a function, they are forced to write implementation > logic, i.e. pointer math to walk the list. > > A bigger issue arises in the fact the very few programmers on > the AS/400 are familiar with or feel comfortable with > pointers but by implementing the service program with a > pointer, you are forcing a consumer of the service program to > use and implement pointers no matter how comfortable they > feel they are in using them. > > Number 3 - No way to validate function. > > The reason that we build small functions is to be able to > have a way to prove that a function works correctly. If we > have a function with that does one thing with a known set of > inputs and known outputs, we can test that function > independently of the program we are working on. In other > words, a black box. > > If a pointer is returned to a consumer, how do you verify > that the function works correctly? You do not have any known > set of outputs. What comes out is completely dependent on the > person who implements the logic. Depending on how they do it, > you will get a different output. The function is un-provable. > > Result of implementation methods. > > I would like to offer an example of how the same problem of > doing disk I/O was implemented in two systems. > In discussing alternative to using pointers, I think we must > first discuss how languages like ILE/RPG are written and implemented. > > The whole concept in creating languages like ILE/RPG is to be > able to break problems down into small pieces and provide for > reusability. The reasons for wanting to do this are obvious > if you have ever tried to debug a 10,000 line monolith > program and tried to change a function that was implemented > differently in a dozen programs. > > We want to be able to write and implement logic in one place. > > When a problem is broken down into small pieces, you have > many small functions that are called over and over again, > maybe thousands of times. In order to accomplish this, you > are going to need the ability to call a procedure or function > very fast. > > That is what ILE/RPG is designed to do. Make maybe 10's of > thousands or more of procedure calls and do it very fast. > > I recently had reason to run some timing tests to test the > speed of a procedure call. > > I did 50 million procedures calls on a unloaded system in 27 > seconds. That works out to about .00000054 seconds per call > and that included passing by value. To say that the AS/400 > and ILE/RPG can do procedure calls fast is an understatement. > This contrasts with doing a subroutine call in .00000044 > seconds per call and a subroutine call is nothing but a jump > to another address. IBM has worked intensively at optimizing > procedure calls to make them as fast as possible and they are > making them faster every release. > > In fact, if we look at the design of languages like ILE/RPG, > they are designed to work this way. They are very efficient > at running programs with many small procedures and local > variables and very inefficient at running very large monolith > programs with tons of static storage. > > My reason for bring this up is that, by necessity, > implementing a solution that does not require using pointers > requires using small functions and calling those functions > many times. > > A concern has been stated that we must use pointers because > we don't want to have the overhead of calling procedures over > and over. > > As previously referred to, implementing a solution would > probably include a function call to BuildAList followed by 1 > to many calls to retrieve each piece of information. > > My point being here that this is exactly the kind of problem > that ILE/RPG was designed to solve and do efficiently. In > other words, worrying about a few hundred billionth of a > second is a waste of time instead of just using the language > the way it was designed. > > In contrast, the consumer of the service only needs to know > what functions they need to call with simple examples and we > can do error checking. If they try to call for record we have > not built, we can issue an error and stop it. If you are > receiving a data structure to load the record in, you can > verify that it is the right size. If the internal structure > changes, all caller that does not receive back all the new > data is not going to fail if he does not need that new data. > > None of this is ideal. In an object oriented language we can > return an object, something we cannot do in ILE/RPG but as a > solution, it far outranges anything we have had to use before. > > Conclusion > > Rather than using pointers, let's use the language the way > the language was designed to be used. Returning pointers from > service programs is almost never a good idea. > > -- > 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. > > ***************************** NOTICE: All e-mail sent to or from this e-mail address will be received or otherwise recorded by The Sharper Image corporate e-mail system and is subject to archival, monitoring, and review by and/or disclosure to Sharper Image security and other management. This message is intended only for the use of the addressee and may contain information that is privileged and confidential. The contents of this message may contain personal views which are not the views of The Sharper Image. If you are not the intended recipient, dissemination of this communication is prohibited. *****************************
As an Amazon Associate we earn from qualifying purchases.
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.