• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Guru: Dynamic Arrays Come To RPG – Limitations, Circumventions, And More

    October 12, 2020 Jon Paris

    In my first two tips in this series I covered the basics of automatic sizing arrays and variable sized arrays. In this final part am going to discuss some of the current limitations in this support and the facilities IBM has put in place to help circumvent them.

    IBM publishes an extensive list of the limitations, but in normal usage only a couple present “real” restrictions in practical terms. If you are curious though, you can find the full list here.

    Limitations

    The first limitation to bear in mind is that, currently, only top-level variables can be defined with DIM(*VAR) or DIM(*AUTO). That is to say Data Structure (DS) arrays or Standalone arrays. So an array within a DS cannot be variable in length. This makes sense if you think about it since it would cause any fields that follow the array in the DS to “move” as the length of the array expanded and contracted.

    The second, and more significant, limitation is that a variable length array cannot be specified on a prototype, either as a parameter or as a return value. This is not to say that such arrays cannot be passed as parameters. They can, as you will see shortly, but they cannot be defined as such on prototypes. The primary reason for this is that RPG’s dynamic arrays have no direct equivalent in other ILE languages and therefore there is no formal IBM i mechanism for passing the current length along with the array’s data.

    IBM have stated that they may add support for these features in the future but I’m not going to hold my breath. I suspect their implementation will depend on how much use RPGers make of the capability and whether they take the time to write up RFEs to demand such enhancements.

    Passing Variable Arrays as Parameters

    In order to pass a varying dimension array as a parameter, it must be specified on the prototype as an ordinary array, i.e. with a regular DIM(nn) keyword. In addition OPTIONS(*VARSIZE) will be required so that the compiler will not get upset about the fact that the initial size of the array is zero elements. Note that since only the array data is passed, it will normally be necessary for you to pass the current active length to the called routine as a separate parameter so that it can identify how many of the elements are active.

    Let’s first look at a simple example of a calling program that passes a variable array as a parameter. We’ll look at the called program shortly. Note that this program is just a test harness that will ask for the number of elements to fill, generate that test data, and then pass the resulting array to a second program.

    (A) We begin by defining the array as being Automatic sized (*AUTO) with a maximum number of elements of 100.

    (B) Note that when defining the array on the prototype I specified the dimension as being 100 (the maximum that it could be) and that the *Varsize option must be specified so that the compiler will accept an array smaller than the maximum (in other words, if our array contains fewer than 100 elements.)

    (C) The program now asks how many elements to load and then (D) checks the number requested against the maximum that the array can hold, substituting the maximum for the requested number if needed.

    Note that although I chose to hard code the array size in the prototype definition, there is a %ELEM option that I could have been used to set the array size. This would make the program more flexible. So instead of coding DIM(100) I could have used DIM( %ELEM( dynarray : *MAX ).

    At (E) I then simply store generated values in the requested number of elements before calling the DYNARRAY6C program which will display the array contents.

    Notice that when the program is called the current active element count (i.e. %ELEM) is passed as a parameter so that the operation of the called program can be limited to the active elements.

    (A)   dcl-s  dynArray  int(5)  Dim( *Auto : 100 );
    
          dcl-s  count  int(5);
          dcl-s  i      int(5);
          dcl-s  wait   char(1);
    
          dcl-pr  DynArray6C  ExtPgm;
    (B)       array     Int(5)  Dim(100)  Options(*VarSize);
              elements  int(5);
           End-Pr;
    
    (C)    Dsply 'How many elements should I load?' ' ' count ;
    
    (D)    If count > %Elem(dynArray : *max );  // Use max if > max requested
              count = %Elem(dynArray : *max );
           EndIf;
    (E)    // Fill requested number of array elements with values
           For i  = 1 to count;
              dynArray(i) = i + count;  // Add new element
           EndFor;
    
           // Now call program notifying it of current element count
    (F)    DynArray6C ( dynArray: count );
    
           Dsply 'All done! - Hit enter to terminate' ' ' wait;
    

    There is really nothing special about the called program — it receives and processes the array using the second parameter received to avoid accessing data beyond the actual current size of the array. As you can see at (G) the procedure interface mirrors the prototype definition. And yes, I should have been a good boy and had the prototype in a copy member and /copied it in here too but since this is just a teaching example I opted for simplicity.

    You can see at (H) that the program uses the count supplied by the caller to limit its access to only those elements that are valid. Who knows what lurks in the storage locations beyond the number of active elements in the passed array!

          
           dcl-s  i      int(5);
    
    (G)    dcl-pi  DynArray6C  ExtPgm;
              array     int(5)  Dim(100);
              elements  int(5)  Const;
           End-Pi;
    
           Dsply ( 'Received ' + %Char(elements) + ' elements');
    
           Dsply 'Values are:';
    
    (H)    For i = 1 to elements;
              Dsply ('Element ' + %Char(i) + ' has the value ' + %Char(array(i)) );
           EndFor;
    

    That’s all there is to it. Or is it? What if the called program needs to add new elements to the array? How could we handle that?

    Never fear, the good folks at IBM have thought of this.

    Adding Array Entries

    There are two things to consider here. First that if the called routine is going to add records to the array, then we need to be sure that there is sufficient memory allocated to the array to allow this. Second, the called routine must notify us of the updated active element count so that we can reset that count on return. Note that this would also have to be done had the called routine deleted array entries – not just added them.

    The vast majority of the logic in the two programs is basically the same as in the two programs above, so I am just going to highlight the significant changes.

    In the calling program, at (I) I use %ELEM with the *ALLOC option to ensure that sufficient memory has been allocated to the array to contain the maximum number of possible elements. Note that this has no effect on the number of active elements, just to the memory allocation.

    After the call I then use %ELEM to set the active element count to accommodate any increase/decrease in the number of elements as determined by the called program. The critical thing to note here is the *KEEP option. It basically prevents RPG from performing any initialization on any new elements. Without this should, for example, the active count go from 10 before the call to 25 after, then RPG would normally initialize elements 11 to 25 to their default values. Not a good idea since all the values just added by the called routine would be nuked. *KEEP tells RPG that you are quite happy with the values currently in those array slots and that they should not be initialized.

           // Allocate sufficient space for the maximum elements
    (I)    %Elem(dynArray : *ALLOC ) = %Elem(dynArray : *Max );
    
           // Now call program notifying it of current element count
           DynArray7C ( dynArray: count );
    
           // Reset active element count preserving new values
           //   that have been added by called program
    (J)    %Elem( dynArray : *KEEP ) = count;
    

    Since the called program doesn’t know the array it was passed is dynamic, there is no special logic needed.

    Here I simply loop though all the active elements in the array (K) modifying each entry in turn just to demonstrate that they can be updated.

    I then increment the active element count that was passed to me (L) and use this to set the value 12345 in that new element. The value in the element count (the elements field which was passed to this program as a parameter) has been updated to account for the new entry. This is the value that is subsequently used by the caller to reset the active element count back in the calling program above at (J).

    (K)    For i = 1 to elements;
              array(i) += i; // Increase value of each element by i
           EndFor;
    
           // Now add an extra element to the array
    (L)    elements += 1;
           array(elements) = 12345;
    

    Summary

    I think these new types of arrays are a very useful addition to the RPG language. For those of you who have been programming in RPG for years they may not seem that exciting, but for newcomers to the language they just help to remove one more barrier to RPG being accepted as the excellent business language that it is.

    Hopefully over this series I’ve given you a good idea of the way these new types of array work and how to overcome the primary limitation of the current support. If you have any questions or comments please let me know.

    Jon Paris is one of the world’s foremost experts on programming on the IBM i platform. A frequent author, forum contributor, and (prior to Covid-19) speaker at User Groups and technical conferences around the world, he is also an IBM Champion and a partner at Partner400 and System i Developer. He hosts the RPG & DB2 Summit twice per year with partners Susan Gantner and Paul Tuohy.

    RELATED STORIES

    Guru: Dynamic Arrays Come To RPG – The Next Part Of The Story

    Guru: Dynamic Arrays Come To RPG

     

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags: Tags: 400guru, dynamic array, FHG, Four Hundred Guru, IBM i, ILE, RPG

    Sponsored by
    Rocket Software

    Unlock the full potential of your data with Rocket Software. Our scalable solutions deliver AI-driven insights, seamless integration, and advanced compliance tools to transform your business. Discover how you can simplify data management, boost efficiency, and drive informed decisions.

    Learn more today.

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    IBM Goes All-In On Hybrid Cloud Thoroughly Modern: Speed Up Application Development With Automated Testing

    Leave a Reply Cancel reply

TFH Volume: 30 Issue: 63

This Issue Sponsored By

  • New Generation Software
  • Fresche Solutions
  • UCG Technologies
  • WorksRight Software
  • Raz-Lee Security

Table of Contents

  • Db2 And SQL Services Get Upgrades With TRs
  • Thoroughly Modern: Speed Up Application Development With Automated Testing
  • Guru: Dynamic Arrays Come To RPG – Limitations, Circumventions, And More
  • IBM Goes All-In On Hybrid Cloud
  • Tweaks To Power System Iron Complement TR Updates

Content archive

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

Recent Posts

  • Meet The Next Gen Of IBMers Helping To Build IBM i
  • Looks Like IBM Is Building A Linux-Like PASE For IBM i After All
  • Will Independent IBM i Clouds Survive PowerVS?
  • Now, IBM Is Jacking Up Hardware Maintenance Prices
  • IBM i PTF Guide, Volume 27, Number 24
  • Big Blue Raises IBM i License Transfer Fees, Other Prices
  • Keep The IBM i Youth Movement Going With More Training, Better Tools
  • Remain Begins Migrating DevOps Tools To VS Code
  • IBM Readies LTO-10 Tape Drives And Libraries
  • IBM i PTF Guide, Volume 27, Number 23

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 © 2025 IT Jungle