|
I get the following compile error when try to assign a pointer to a const variable. Did I do something wrong? RNF7586 20 52 001800 The address of a constant value is used incorrectly.
If you read my previous message carefully, you'll see that I already told you that would happen :) The compiler won't let you assign the address of a CONST field to a pointer because the compiler doesn't want you to be able to modify the CONST field. If you had a pointer to the field, you'd be able to modify it... and it's trying to prevent that.
Like I said, it only does this checking at compile time. You get an error in your compile listing (indeed, the very error you show above) and your program isn't created.
My message was discussing *tricking* the compiler. The goal is to trick the compiler into thinking you're doing everything legitimately so that it lets you by...
And again, like I said before -- I don't consider this a good practice. I don't recommend that you do it. You're deliberately bypassing the compiler's safeguards, and I never recommend that.
However, I still do it because there are times when I must. I'm always very careful not to modify the field -- but I absoltely must get a pointer to it, even if I don't use the pointer to change the data. This same technique can be used to solve the optional parameter dilemna -- but all I'm saying is that it CAN be used, not that I recommend it.
Clear as mud? Thought so. So I'll illustrate what I mean with code.The following is a complete program. You can copy/paste it into WDSC (or Notepad, and then upload it to your system -- or, if you're like me, you can copy/paste it into vi. I'm sure that's the route Jon Paris would take, since I know he loves vi -- but anyway...)
Take this program and try it out. Step through it in debug. See how it works...
H DFTACTGRP(*NO) D HandleOptParm PR * extproc('REAL_HANDLEOPTPARM') D Num 10I 0 value D Total 10I 0 value D parm 65535A const options(*varsize:*omit) D local 65535A options(*varsize) D real_HandleOptParm... D PR * D Num 10I 0 value D Total 10I 0 value D parm * value D local * value D my_sub_proc PR D field1 10A const D optField2 10A const options(*nopass:*omit) D optField3 10A const options(*nopass:*omit) D var1 s 10A inz('BlahBlah') D var2 s 10A inz('HalbHalb') /free dsply ('Using default values, you get:'); my_sub_proc('nopass'); dsply ('Using *OMIT, you get:'); my_sub_proc('omit': *omit: *omit); dsply ('Passing only one value, you get:'); my_sub_proc('oneval': 'foo foo'); dsply ('Omitting only one value, you get:'); my_sub_proc('omitone': *omit : 'bar bar'); dsply ('Using literals you get:'); my_sub_proc('literal': 'one': 'two'); dsply ('Using variables you get:'); my_sub_proc('variable': var1: var2); *inlr = *on; /end-free *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * demonstration of calling HandleOptParm *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ P my_sub_proc B D my_sub_proc PI D field1 10A const D optField2 10A const options(*nopass:*omit) D optField3 10A const options(*nopass:*omit) D dftField2 s like(Field2) inz('DefaultVal') D dftField3 s like(Field3) inz('OtherDft') D Field2 s like(optField2) D based(p_Field2) D Field3 s like(optField3) D based(p_Field3) /free p_Field2 = HandleOptParm(2:%parms:optField2:dftField2); p_Field3 = HandleOptParm(3:%parms:optField3:dftField3); // do whatever you need to do. Always reference // "Field2" or "Field3" (never the "opt" or "dft" copies) // For the sake of demonstration, I'll use DSPLY to show // the values of Field1, Field2 and Field3 dsply ('field1=' + field1); dsply ('field2=' + field2); dsply ('field3=' + field3); /end-free P E *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * HandleOptParm(): Handle optional parameters * * Note: Never call this via the "real_HandleOptParm" interface. * that's only there to trick the compiler. * * Num = (input) parameter number * Total = (input) total number of parameters (%parms) * parm = (input) parameter to handle * local = (input) local workspace if parm was not passed * * Returns the address of the parmeter, or the local space * if the parameter wasn't passed. *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ P real_HandleOptParm... P B export D real_HandleOptParm... D PI * D Num 10I 0 value D Total 10I 0 value D parm * value D local * value /free if ( Total >= Num and parm<>*NULL ); return parm; else; return local; endif; /end-free P ENote: Under ordinary circumstances, the "real_HandleOptParm" procedure would go into a service program. The prototype for "real_HandleOptParm" (which I don't expect anyone to ever use) would go into the same member as the subprocedure itself, and would never be in a /COPY book.
The HandleOptParm prototype would go in the copy book. Also, this demonstration only shows character fields. You can use the same technique with any data type, you just need to make a different "HandleOptParm" prototype (the subprocedure itself doesn't need to be diplicated, only the prototype -- if you understand how the subproc works, you should see why.)
Anyway, you put that in a service program and copy book so that you don't have to repeat them in every program/procedure. All you need to do in the actual program/procedure is this part:
p_Field2 = HandleOptParm(2:%parms:optField2:dftField2); p_Field3 = HandleOptParm(3:%parms:optField3:dftField3);Plus, of course, the field defifinions for the "dftField" fields, and the "Field1, Field2" etc definitions... But I think coding those two lines of code is cleaner than lots of the following in every single procedure:
if %parms>=2 and %addr(optField2); // do this else; // do that; endif; if %parms>=3 and %addr(optField3); // do this else; // do that; endif; Anway, let me know what you think....
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.