ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Omissible procedure pointer parameters

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Omissible procedure pointer parameters

    I ran into this issue today -

    I coded a procedure in a service program, that has amongst its parameters
    Code:
    MyCallback pointer(*proc) const options(*nopass:*omit);
    I called the procedure, passing *OMIT.

    The procedure has a line
    Code:
    if  (%parms() >= %parmnum(MyCallBack))
    And that line died with one of those "pointer reference not set" errors.

    I don't have this issue with parameters of other types, including data pointers.

    Does RPGLE not like having *OMIT passed on a procedure pointer parameter?
    Does it not like CONST there?

    (I passed in *NULL instead, that works).


  • #2
    Are you sure it is dying on that IF? There is no pointer resolution required for this code to run. It is more likely that you are subsequently trying to use MyCallback on a call when it is set to null. Remember, when you pass *Omit a parm is still passed (a null pointer) so if the %Parms value indicates that there may be a parameter there, you must still test the pointer before using it so the IF needs to be:

    Code:
    if (%parms() >= %parmnum(MyCallBack)) AND %Addr(MyCallback) <= *Null;
    // Now it is safe to use MyCallBack
    Last edited by JonBoy; February 13, 2023, 12:11 PM. Reason: Vectorspace's post made me realize that %addr was needed.

    Comment


    • #3
      To clarify. *NOPASS means the parameter does not need to be included on the call.
      E.g. If the proc has 4 parms and the last 3 have *nopass, you can pass:
      * 1 myProc('a');
      * 1-2 myProc('a':'b');
      * 1-3 myProc('a':'b':'c');
      * 1-4 myProc('a':'b':'c':'d');

      You test for this using %parms vs %parmnum
      But you cannot use it to e.g., only pass 1 and 4. You cannot skip intermediary params.


      *OMIT means you can omit intermediary params, by passing *omit into them. E.g. myProc('a': *omit: *omit: 'd')
      Using *omit means it passes in a null pointer instead of an actual pointer/value
      You usually test for this using %addr(parm) = *null to see if the parameter has a null pointer
      However your parameter is a pointer, so I don't know if you need to use %addr, or if you should just directly test if it's null.

      You'll usually use a combination of both.

      Comment

      Working...
      X