|
On Mon, 2003-10-27 at 22:24, Jon Paris wrote: <snipped stuff> > If it is a data type mismatch then it _may_ blow up - but not always, and > not predictably. A packed field will appear perfectly valid for character > operations, but introduce (say) spaces into it in the called routine and > you'll have lots of fun later. If you have never experienced this then all > I can say is that you have been lucky. However, we are not just talking > about data types. In fact corruption is more likely to occur with > mismatched lengths - e.g. passing a ten character field to a routine that > expects 20. For the archives I feel I should share here: I learned this lesson the hard way a couple of years ago. I had a procedure that was originally written to accept a 128 long character string. One day I decided that it needed to be 512, so I changed my Interface, changed the prototype, compiled it, and UPDSRVPGMed it. Thinking that all was well I went on my merry way. Of course, what had happened was that now there were programs that were compiled with the old prototype that had not been recompiled or UPDPGMed, so in the updated version of the procedure I was getting 512 bytes of memory space even though the program was still only sending 128. Needless to say, I've never forgotten that lesson. > The critical point is that if you are expecting the system to check for you > then you are in for a nasty surprise at some point in time. > > Given that this conversation is about subprocedures - which means bound > calls - we should also consider them here. They work differently and there > is far less likelihood of a "missing" parm causing an immediate error since > there may well be a valid pointer on the stack - it just won't be to the > right data! I now try my best to not change interfaces once I have them in place... that's not to say I won't add parms. I'll do that and make them option(*nopass), which if properly written will continue to function. If I really need to change an interface, I'll write a new version of the procedure, add it to the same service program as the old one, and through "dual prototyping" I can change the name so that it slowly filters. Here is an example of Dual prototyping from when I increased this proc parameter from 512 to 32000: d allUpperCase pr 32000a varying extproc('RNALLCAPS2') d NotCaps 32000a value varying d RNAllCaps2 pr 32000a varying d inString 32000a value varying The procedure RNALLCAPS2 replaced RNALLCAPS: d RNAllCaps pr 512 varying d NotCaps 512 value varying By adding an additional layer or prototyping (see 'allUpperCase' in the first example), I was able to change the EXTPROC statement and the prototyping without changing any program code. Value or Const will handle any parameter mismatches for me, and now the same calls are using the new procedure. Naturally one would have to find and update any programs that needed this change, but most of the time this is a gradual process. This approach has the added benefit of allowing the developer to name the procedure calls whatever he/she wants. Joel http://www.rpgnext.com
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.