|
>>Given that we have a procedure with a VARYING string of 32767 passed by reference >>and I decide in a calling program to pass a normal field char(20), what is going to happen? A pointer to the 20 byte field is passed to the procedure. But if you do not specify neither VALUE nor CONST your calling procedure will not compile. If you specify VALUE a temporary field with 32K varying length is generated and this field passed to the called procdure. If you specify CONST a temporary field with 32K varying length is generated, but only the address of this new field is passed to the called procedure. In both cases the parameters are input only, that means the calling procedure will never get the parameter back. If you have output parameters where you expect different length, you should define the parameter field with fixed length. Add the keyword OPTION(*VARSIZE) and add the keyword OPDESC to the prototype, to use operational descriptors. In this case the pointer of the original field, and not a duplicate, is passed to the called procedure. In your called procedure you have to call the API CEEDOD to determine the number of bytes passed. In your called procedure you have to take care, not to change more than the passed bytes. Otherwise you will override some bytes that are used by an other field may be in an other procedure. First time I used this szenario, I cleared the complete parameter field with CLEAR. It took me 2 days to fix the problem! Birgitta -----Ursprungliche Nachricht----- Von: rpg400-l-bounces@xxxxxxxxxxxx [mailto:rpg400-l-bounces@xxxxxxxxxxxx]Im Auftrag von Alan Campin Gesendet: Donnerstag, 26. Mai 2005 23:04 An: RPG programming on the AS400 / iSeries Betreff: RE: VARLEN field read into LIKEREC DS My point about the changing code was that I just use a 32767 as a routine size for a VARYING field rather than trying to figure out what length to make it. I based this on the assumption that the field would never occupy more than the current size of the string but you are saying that if I set the max to 32767, I am going to get cut out 32K of storage so I need to look at reducing these field size although this does raise an interesting question. Given that we have a procedure with a VARYING string of 32767 passed by reference and I decide in a calling program to pass a normal field char(20), what is going to happen? According to what you have said, the VARYING field is 32767 but I calling the field is only 20 bytes. Under my scenario, I would simply get a 20 byte field but according to your scenario I would get a 32767 length field. So the operating system creates a 32k field, copies the 20 bytes to it, calls the procedure and upon return, copies the field back to the original 20 byte field? Since I have a VARYING string in the called procedure, I could change the length of the string to 100 bytes but on return I only have a 20 byte field. What happens? Does it just truncate the value, throw an error? If I pass by VALUE, I don't see a conflict because the 20 bytes would be copied to a 32K field and discarded on return but this by reference bothers me. Thanks for the help. -----Original Message----- From: Barbara Morris [mailto:bmorris@xxxxxxxxxx] Sent: Thursday, May 26, 2005 11:28 AM To: rpg400-l@xxxxxxxxxxxx Subject: Re: VARLEN field read into LIKEREC DS Alan Campin wrote: > > Ouch, so you are saying if I declare a VARYING field to be 32767 which I routinely do, it takes 32K of storage? I thought the amount of storage was equal to the current string length + 2 bytes. If I do %LEN(string) = 0, the length of the string was zero. Are you saying that even though I set it's length to zero, it still occupies 32K of storage? > > Doesn't that kind of defeat of the whole purpose of VARYING? I thought the whole idea was that I could declare strings and not have to worry about these issues? What advantages would I get using VARYING over simply declare a string of 32K other than being able to say %LEN? The purpose of VARLEN in the DDS is to possibly reduce storage in the database. The purpose of VARYING is more to give better performance and easier coding of string manipulation (and also just to support using the VARLEN fields that the database provides). > > I routinely pass in varying string as parameters by value but I guess I hear that the system is going to have to copy the whole 32K to the stack? Yes. It's better to pass varying strings as CONST, even if you have to copy the parameter to a temporary within the procedure in the cases where you want to modify the parameter. > > I know that %SIZE returns the maximum + two bytes but not that it was reading the actual length of the string. The compiler knows the maximum length of the string at compile time so that it would just insert the value at compile time. I was trying to think of a scenario were the compiler would not the maximum string length at compile time but can't think of one. %SIZE isn't reading the whole length of the string. %SIZE is a compile-time value that is always the same. My point was that %SIZE gives you the number of storage bytes occupied by the string, and that the number of storage bytes is constant. > > I was thinking about this issue the other night and it seemed to me that best possibility was that each VARYING string always occupied 18 bytes. 2 bytes for the length and a pointer to the actual storage so if I set the value to zero, the storage was released. If I changed it to 20 bytes, I would have internally a pointer to the allocated storage but I guess you are saying no. This is done because doing allocations would take too much resources? When VARYING fields were introduced to RPG, the format of the fields in the database was already set. I don't know if the database format ever considered using pointers as you describe. I don't know what would be the relative performance of doing runtime-allocations vs allocating the full length. There's nothing to say that an alternate form of varying length field couldn't be added to the language. If RPG ever gets strings longer than 65535, some new form of varying length will _have_ to be introduced (if only a 4-byte length prefix), since the 2-byte prefix only holds lengths up to 65535. > > Ouch, ouch. Going to have to change a lot of code. I hope you just mean changing your the parameters from VALUE to CONST. I wouldn't stop using varying fields since they perform much better than fixed length fields if the alternative is doing repeated %TRIM operations to get the actual data. The storage required by a varying field is only 2 more than the equivalent fixed-length field. -- 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 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.