• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Basing Pointer Variables in RPG: The Basics

    September 15, 2010 Ted Holt

    When I began pursuit of my computer science degree eons ago, the only programming experience I had was business programming. Jumping from System/34 RPG II to Pascal was a shock, but learning Pascal was one of the best things that ever happened to me professionally. Learning Pascal introduced me to programming constructs that I had not seen before, including pointer variables, the topic of this article. If you’ve not mastered pointers, continue reading. Do it for your own edification.

    RPG has two types of pointer variables: basing pointers, and procedure pointers. Both types of pointers hold memory addresses. Both types of pointers provide a way to indirectly access something else. This article deals only with basing pointers.

    Your Address, Please

    Basing pointers are variables, but they don’t store the types of data to which we are accustomed, such as names, addresses, account numbers, quantities, and currency amounts. Basing pointers store the memory addresses of data. They are indicated by an internal data type of asterisk (*) in position 40 of the definition specification. Here’s a basing pointer named Address.

    DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++++++
    D Address         s               *
    

    A basing pointer has a null value by default. That is, it doesn’t point to any data at all.

    So, if a basing pointer can store an address of data, but cannot store the data itself, where is the data to which the basing pointer points? The simple answer is that the data is somewhere else. That unknown “somewhere else” is represented by a based variable. Here is a basing pointer, PtrName, and a character variable, Name, to which the basing pointer points.

    D PtrName         s               *
    D Name            s             20a   based(PtrName)
    

    The Name variable has no place of its own in memory, so it must share memory that has been allotted to something else. To do that, assign the address of another variable to the pointer. (There is another method–use the %alloc function or the ALLOC op code to allocate memory for the based variable–but that will buy us nothing for this discussion.)

    To see how it works, consider this example.

    D AddressOfTheSelectedVar...
    D                 s               *
    D TheSelectedVar...
    D                 s             20a   based(AddressOfTheSelectedVar)
    D*
    D Name            s             20a
    D Address         s             20a
    D City            s             20a
    D
     /free
         *inlr = *on;
         AddressOfTheSelectedVar = %addr(Name);
         TheSelectedVar = 'John Dilatory';
         AddressOfTheSelectedVar = %addr(Address);
         TheSelectedVar = 'P. O. Box 1';
         AddressOfTheSelectedVar = %addr(City);
         TheSelectedVar = 'Lost Angeles';
         return;
    

    In addition to the basing pointer and based variable, there are three static variables: Name, Address, and City. This short routine assigns values to the three static variables, but it does so indirectly. The second assignment statement retrieves the memory address of Name and stores that memory address in the basing pointer AddressOfTheSelectedVar. Now Name and TheSelectedVar refer to the same 20 bytes of memory, which means that changing one changes the other.

    After this code runs, Name, Address, and City contain the values John Dilatory, P. O. Box 1, and Lost Angeles, respectively.

    Let’s Be Practical

    Let’s consider a more practical example. Suppose we have a command named DOIT (do it).

    CMD        PROMPT('Do it')
    PARM       KWD(WHEN) TYPE(*TIME) MIN(1) MAX(6) +
                 PROMPT('Time to do it')
    

    Notice that DOIT has a list parameter, WHEN, which allows the user to specify from one to six times that “it” should be done.

    DOIT WHEN(080000 123000 144500 180000)
    

    The system formats the time values into a variable-length string. The first two bytes contain a binary number that tells how many values were keyed into the parameter. Following that are a series of one to six 6-byte character values. The system will send either eight, 14, 20, 26, 32, or 38 characters to the command-processing program.

    While we’re supposing, let’s suppose that the command-processing program is written in RPG. How is the RPG program to interpret the list of time values? Before pointers, an RPG program would have to define the parameter with a length of at least 38 bytes.

    Suppose the command is changed so that a maximum of 10 values can be keyed into the WHEN parameter. The length of the list parameter in the RPG program would have to be changed from at least 38 to 62.

    However, if you use pointers to process the list, the program does not have to be changed. Look at this:

    ****   *entry plist
    D 
    D DoItCPP         pr
    D parmWhen                       1a
    D DoItCPP         pi
    D parmWhen                       1a
    
    D ListPointer     s               *
    D NbrOfListElems  s              5i 0 based(ListPointer)
    D TimeInList      s              6a   based(ListPointer)
    
    D NbrOfTimes      s              5i 0
    D Ndx             s             10i 0
    D TimeVar         s              6a
    
     /free
         *inlr = *on;
    
         // How many time values were passed in?
         ListPointer = %addr(parmWhen);
         NbrOfTimes  = NbrOfListElems;
    
         // Advance to the first time value.
         ListPointer += 2;
    
         // Loop to extract the time values.
         for Ndx = 1 to NbrOfTimes;
            TimeVar = TimeInList;
    
            // Here's the place do something with TimeVar.
    
            // Advance to the next time value in the list.
            ListPointer += %size(TimeInList);
         endfor;
    
         return;
    

    The input parameter, parmWhen, is defined as a 1-byte character value. That’s obviously incorrect, but it doesn’t matter, because all we need is the address of the parameter.

    In the calcs, extract the number of time values from the first 2 bytes of the parameter.

    D ListPointer     s               *
    D NbrOfListElems  s              5i 0 based(ListPointer)
    
    D NbrOfTimes      s              5i 0
    
     /free
         ListPointer = %addr(parmWhen);
         NbrOfTimes  = NbrOfListElems;
    

    Advance the pointer 2 bytes so that it points to the first 6-byte time value.

         ListPointer += 2;
    

    Process the time values in the list.

         // Loop to extract the time values.
         for Ndx = 1 to NbrOfTimes;
            TimeVar = TimeInList;
    
            // Here's the place do something with TimeVar.
    
            // Advance to the next time value in the list.
            ListPointer += %size(TimeInList);
         endfor;
    

    Each iteration loads the next time into TimeVar and advances the pointer 6 bytes so that it points to the next time value in the list. After the last iteration, ListPointer is pointing to the first byte in memory that follows the list, but that’s OK as long as we don’t use ListPointer while it has that value.

    If someone changes the MAX parameter of the DOIT command, the system will send strings of other lengths, but since the length of parmWhen is not specified in the parameter definition, the RPG program will not need to be changed.

    Broaden Your Horizons

    If you don’t know how to use basing pointers, you may as well learn. Basing pointers are not difficult to understand. They especially come in handy when dealing with the data returned from certain APIs. And they’re fun.



                         Post this story to del.icio.us
                   Post this story to Digg
        Post this story to Slashdot

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    Maxava

    Migrating to New IBM i Hardware?

    Whether you are moving to POWER9, Power10, or a cloud hosted system MAXAVA HAS YOU COVERED!

    Learn More

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Sponsored Links

    iSeries DevCon2010:  Get 3 days of IBM i training and 365 DAYS OF VALUE, Nov 15-17, Las Vegas
    looksoftware:  RPG OA & Beyond Webinar. Sept 28 & 29. Enter to win an Amazon Kindle™
    COMMON:  Join us at the Fall 2010 Conference & Expo, Oct. 4 - 6, in San Antonio, Texas

    IT Jungle Store Top Book Picks

    Easy Steps to Internet Programming for AS/400, iSeries, and System i: List Price, $49.95
    The iSeries Express Web Implementer's Guide: List Price, $49.95
    The System i RPG & RPG IV Tutorial and Lab Exercises: List Price, $59.95
    The System i Pocket RPG & RPG IV Guide: List Price, $69.95
    The iSeries Pocket Database Guide: List Price, $59.00
    The iSeries Pocket SQL Guide: List Price, $59.00
    The iSeries Pocket Query Guide: List Price, $49.00
    The iSeries Pocket WebFacing Primer: List Price, $39.00
    Migrating to WebSphere Express for iSeries: List Price, $49.00
    Getting Started With WebSphere Development Studio Client for iSeries: List Price, $89.00
    Getting Started with WebSphere Express for iSeries: List Price, $49.00
    Can the AS/400 Survive IBM?: List Price, $49.00
    Chip Wars: List Price, $29.95

    m-Power Gets ‘What If’ Analysis The More Things Change

    Leave a Reply Cancel reply

Volume 10, Number 27 -- September 15, 2010
THIS ISSUE SPONSORED BY:

WorksRight Software
Profound Logic Software
inFORM Decisions

Table of Contents

  • Get Thee to the Web, Part 2
  • Basing Pointer Variables in RPG: The Basics
  • Admin Alert: Getting Started with i/OS Security Auditing, Part 1

Content archive

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

Recent Posts

  • LANSA Developing Business Intelligence Tool
  • Blazing The Trail For VTL In The Cloud
  • Data De-Dupe Gives VTL Customers More Options
  • Four Hundred Monitor, March 29
  • The Big Spending On IT Security Is Only Going To Get Bigger
  • IBM Tweaks Some Power Systems Prices Down, Others Up
  • Disaster Recovery: From OS/400 V5R3 To IBM i 7.4 In 36 Hours
  • The Disconnect In Modernization Planning And Execution
  • Superior Support: One Of The Reasons You Pay The Power Systems Premium
  • IBM i PTF Guide, Volume 25, Number 13

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