• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • CONST Doesn’t Mean You Can’t Change It

    October 20, 2015 Ted Holt

    You can pass parameters to an RPG subprocedure in three ways: by reference, by read-only reference, and by value. (I have written about this before.) My favorite method is read-only reference. I use it as often as I can. Would you believe that it is possible to change the value of a variable that is passed to a subprocedure by read-only reference? Since you would probably do so only inadvertently, it’s good to understand how it can happen.

    To pass a parameter by read-only reference, include the CONST keyword in the procedure prototype and the procedure interface.

    D Process         pr
    D  inSection                          like(Section) const
    
    P Process         b
    D                 pi
    D  inSection                          like(Section) const
    

    If the program from which this code was taken tries to modify inSection within the Process subprocedure, like this:

    eval inSection = 'XX'
    

    The compiler heartlessly responds with message RNF5346: “The operation modifies the field, but the field cannot be modified.” And so the compilation fails.

    No, to modify inSection, you have to be sneaky. (Or in my case, stupid.) Here’s how it’s done.

    Assume a database table:

    create table Specs
       (Section    char(2),
        Sequence   dec(3),
        Position   dec(3),
        Text       char(50),
       primary key (Section, Sequence))
       rcdfmt Spec;
    
    insert into Specs values
    ('BB',  1,  1, 'XXXXXXXXXXXXXXX'),
    ('BB',  2,  1, 'XXXXXXXXXXXXXXX'),
    ('BB',  3, 13, 'XXX'), ('BB',  4, 12, 'XXX'),
    ('BB',  5, 11, 'XXX'), ('BB',  6, 10, 'XXX'),
    ('BB',  7,  9, 'XXX'), ('BB',  8,  8, 'XXX'),
    ('BB',  9,  7, 'XXX'), ('BB', 10,  6, 'XXX'),
    ('BB', 11,  5, 'XXX'), ('BB', 12,  4, 'XXX'),
    ('BB', 13,  3, 'XXX'), ('BB', 14,  2, 'XXX'),
    ('BB', 15,  1, 'XXX'), 
    ('AA',  1,  4, 'XXXXXXXXX'),
    ('AA',  2,  2, 'XX         XX'),
    ('AA',  3,  1, 'XX           XX'),
    ('AA',  4, 11, 'XXX'),
    ('AA',  5,  9, 'XXX'),
    ('AA',  6, 11, 'XXX'),
    ('AA',  7,  1, 'XX           XX'),
    ('AA',  8,  2, 'XX         XX'),
    ('AA',  9,  4, 'XXXXXXXXX');
    

    Here’s a printer file:

    A          R HEADER                    SKIPB(1)   
    A                                     1'==BEGIN=='
    A          R DETAIL                    SPACEB(1)  
    A            MESSAGE       80         1           
    A          R TRAILER                   SPACEB(1)  
    A                                     1'==END=='  
    

    And finally, an RPG program:

    H dftactgrp(*no) actgrp(*new) option(*srcstmt: *nodebugio)
    
    FSpecs     if   e           k disk
    FQAD0040P  o    e             printer
    
    D Process         pr
    D  inSection                          like(Section) const
    
     /free
         *inlr = *on;
         read Spec;
         dow not %eof(Specs);
            write Header;
            Process (Section);
            write Trailer;
         enddo;
         return;
     /end-free
    
    P Process         b
    D                 pi
    D  inSection                          like(Section) const
     /free
         dow not %eof(Specs)
         and Section = inSection;
            clear Message;
            %subst(Message: Position) = Text;
            write Detail;
            read Spec;
         enddo;
     /end-free
    
    P Process         e
    

    Notice the Process subroutine. Its purpose is obviously to print all the data for whichever section is specified in the inSection parameter. Just glancing at the data and this program, you would expect this two-page report:

    ==BEGIN==
       XXXXXXXXX
     XX         XX
    XX           XX
              XXX
            XXX
              XXX
    XX           XX
     XX         XX
       XXXXXXXXX
    ==END==
    < . . . imagine a page break here . . . >
    ==BEGIN==
    XXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXX
                XXX
               XXX
              XXX
             XXX
            XXX
           XXX
          XXX
         XXX
        XXX
       XXX
      XXX
     XXX
    XXX
    ==END==
    

    But, no, you’d get a one-page report, like this:

    ==BEGIN==
       XXXXXXXXX
     XX         XX
    XX           XX
              XXX
            XXX
              XXX
    XX           XX
     XX         XX
       XXXXXXXXX
    XXXXXXXXXXXXXXX
    XXXXXXXXXXXXXXX
                XXX
               XXX
              XXX
             XXX
            XXX
           XXX
          XXX
         XXX
        XXX
       XXX
      XXX
     XXX
    XXX
    ==END==
    

    Here’s why.

    The main routine passes the address of the Section variable to the Process subprocedure. This means that inSection (in the subprocedure) and Section (throughout the entire program) are two names for the same spot in memory. When Process reads the Specs table, the system changes the value of Section, which is also the value of inSection. Consequently, the control break never occurs and the loop stops at end of file.

    Global variables cause a lot of grief and I try to avoid them, but in all fairness, passing lots of parameters between subprocedures can get mighty unwieldy.

    There are several ways to fix this problem. Perhaps the easiest is to pass the section ID by value.

    D Process         pr
    D  inSection                          like(Section) value
    
    P Process         b
    D                 pi
    D  inSection                          like(Section) value
    

    This change gives you the two-page report you expected.

    Here’s another way to change the value of a variable that is passed by read-only reference. I’ll modify the preceding program slightly in order to illustrate.

    H dftactgrp(*no) actgrp(*new) option(*srcstmt: *nodebugio)
    
    FSpecs     if   e           k disk
    
    D Process         pr
    D  inSection                          like(Section)  const
    
    D BR549           pr                  extpgm('BR549')
    D  inSection                          like(Section)  const
    
     /free
         *inlr = *on;
         read Spec;
         dow not %eof(Specs);
            Process (Section);
            read Spec;
         enddo;
         return;
     /end-free
    
    P Process         b
    D                 pi
    D  inSection                          like(Section)  const
    
     /free
         BR549 (inSection);
     /end-free
    
    P Process         e
    

    The program passes the address of Section to subprocedure Process, which knows the parameter as inSection. The subprocedure calls program BR549, passing the section value along by read-only reference. Now let’s take a look at BR549.

    pgm (&inSection)
    
       dcl  &inSection   *char  2
    
       chgvar  &inSection   'ZZ'
       return
    
    endpgm
    

    Even though the RPG program thinks the CL program won’t modify the parameter, the CL program has other ideas. In fact, the CL program doesn’t even know that the RPG program thinks the parameter won’t be modified.

    I highly recommend passing parameters by read-only reference, but be aware that the CONST keyword isn’t foolproof.

    RELATED STORY

    Parameter Passing and Performance

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    DRV Technologies, Inc.

    Get More from Your IBM i

    Many users today struggle to get at the data they need on the IBM i. When users get reports, they look like they were formatted some time last century.

    Some organizations are still printing pre-printed forms and checks on impact printers.

    How often do operators log on to their system to look for messages they hope they don’t find?

    All of these scenarios can affect users’ perception of the IBM platform negatively, but there are simple solutions.

    DRV Technologies Inc. develops innovative solutions that help customers get more from their IBM i systems.

    Solutions include:

    • SpoolFlex spool conversion & distribution
    • FormFlex electronic forms
    • SecureChex MICR laser check printing
    • MessageFlex system monitoring

    FlexTools streamline resources, improve efficiency and enable pro-active system management.

    Better software, better service, DRV Tech.

    Learn how you can get more from your IBM i at www.drvtech.com

    Call 866 378-3366 for a Free Demonstration

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Sponsored Links

    Connectria:  Need help managing your IBM i? Trust us as an extension of your IT department.
    HelpSystems:  How do you use IBM i? Your peers want to know! Take the survey >
    Rocket Software:  Mobile app development and deployment solution for IBM i. Download FREE trial!

    IBM Updates PowerVM Hypervisor, PowerVC OpenStack Accur8 Takes Aim at Data Virtualization Opportunity

    Leave a Reply Cancel reply

Volume 15, Number 21 -- October 20, 2015
THIS ISSUE SPONSORED BY:

WorksRight Software
PowerTech
Storagepipe

Table of Contents

  • Developers Can Improve Security and Reduce the Administrative Cost of Security
  • CONST Doesn’t Mean You Can’t Change It
  • DB2 for i 7.1 TR10 and i 7.2 TR2 Features, Part 2

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • Fortra Issues 20th State of IBM i Security Report
  • FNTS Launches Managed Services for Power Servers in IBM Cloud
  • Total LTO Shipped Capacity Up Slightly in 2022
  • Four Hundred Monitor, May 24
  • Update On Critical Security Vulnerability In PowerVM
  • Critical Security Vulnerability In PowerVM Hypervisor
  • IBM Power: Hosted On-Premises Or In The Cloud?
  • Guru: Watch Out For This Pitfall When Working With Integer Columns
  • As I See It: Bob-the-Bot
  • IBM i PTF Guide, Volume 25, Number 21

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2023 IT Jungle