Pointers on Using Pointers in RPG IV

Suppose you need to display or print the name of the month and to support two different languages. Assuming the month is represented as a number in field Month and field Language contains a code indicating the users language, you might handle the task by writing code that uses two compile-time arrays as shown below. (Notes: For brevity, we havent shown the array content - we figure you can work that out. Weve assumed English as the default language.)


D MonthsEnglish   S              9    DIM(7) CTData PerRcd(1)
D MonthsFrench    S              9    DIM(7) CTData PerRcd(1)

C                   If      Language = 'French'
C                   Eval    MonthName = MonthsFrench(Month)
C                   Else
C                   Eval    MonthName = MonthsEnglish(Month)
C                   EndIf

This isnt so bad if you only need to support two languages and refer to the array in one place in the calcs. But if you need to support more languages and/or you must refer to this array in many places in the program, all that "If... Else" logic gets a bit cumbersome. In this case, you might decide to create a third array and then use a MOVEA operation at the beginning of the program to set the appropriate language data in this generic array. From there, you can simply refer to the generic array name without any additional "If ... Else" type logic:

C                   Eval      MonthName = MonthArray(Month)

D MonthArray      S              9    DIM(7)

D MonthsEnglish   S              9    DIM(7) CTData PerRcd(1)
D MonthsFrench    S              9    DIM(7) CTData PerRcd(1)

C                  If        Language = 'French'
C                  MoveA     MonthsFrench MonthArray
C                  Else
C                  MoveA     MonthsEnglish MonthArray
C                  EndIf

Using a pointer, we can improve on that second approach. The pointer allows us to map the data from the appropriate compile-time array to the generic array without actually moving data. Of course, the efficiency gained by not moving this small array isnt dramatic, but if there were multiple or large data arrays, the efficiency gain could become noticeable.

To use the pointer approach, we must specify that our generic array is "based" on the value of a pointer field. This means that the generic array has no storage allocated to it by the compiler. Instead the program uses the address in the basing pointer to map to some data that exists elsewhere in the program. Then, instead of moving the data from one of the compile-time arrays to the generic array, we simply map the data to the array by setting the basing pointers address to the location of the appropriate language array. The effect is the same, but no array data is physically moved. The code would be similar to this example:

D MonthArray      S              9    DIM(7) BASED(pMonth)

D MonthsEnglish   S              9    DIM(7) CTData PerRcd(1)
D MonthsFrench    S              9    DIM(7) CTData PerRcd(1)

D pMonth          S *    INZ(%ADDR(MonthsEnglish))

C                  If        Language = 'French'
C                  Eval      pMonth = %Addr(MonthsFrench)
C                  EndIf

C                  Eval      MonthName = MonthArray(Month)

A pointer is simply a field that contains the address (or location) of something, such as a data structure or an array. There are many ways to get an address into a pointer. If the item you want to address is inside your RPG program, the simplest way is usually to use the %Addr built-in function, as we did in this example. (Reminder: Never try to refer to a field thats based on a pointer before you've entered a valid address for that pointer. If you do, youll get a function check. In our example, we made sure we had a valid value in the pointer by initializing the value of the pointer field on the D spec. This approach may not always be practical.)

This is, of course, a simple example. You can probably imagine similar scenarios where you may have several sets of data with identical structures but different values (i.e., tax-rate tables for different regions, shipping-rate tables for courier services, postal-rate tables for air, surface, overseas, etc. ).

One fairly common use of pointers is to map the numbered indicator array (*IN) to a data structure to use named indicators in place of numbers in programs. In the example below, the program logic can set on or off an indicator named "DateError," which sets on (or off) *IN32. (Note: This technique is similar - but not identical -- to the INDDS keyword support for display and printer files added in V4R2.) This type of mapping works for all uses of numbered indicators -- not just the indicators used in the file. Also in this example, the use of the numbered and named indicators is interchangeable. In other words, you can set on *IN32 or DateError, and the effect is the same because *IN32 and DateError are just two names for the same byte of data.

D                 DS     Based(pIndicators)
D Exit            3      3N
D Prompt          4      4N
D Cancel          12     12N
D DateError       32     32N

C                   Eval      pIndicators = %Addr(*IN)

So far, weve examined some fairly simple ways to map data within a program to another name or structure using pointers. But pointers arent limited to mapping data inside programs. They can also provide a link to data outside of programs. One of the most common uses for pointers in RPG programs is to map to data in an OS/400 User Space object. Well address this topic in an upcoming column.


Jon Paris is a technical editor with IBM Systems Magazine and co-owner of Partner400.

Susan Gantner is a technical editor with IBM Systems Magazine and co-owner of Partner400.

comments powered by Disqus



2019 Solutions Edition

A Comprehensive Online Buyer's Guide to Solutions, Services and Education.

New and Improved XML-INTO

Namespace support makes the opcode a viable option

Authenticating on the Web

The finer points of OpenRPGUI, Part 1

The Microphone is Open

Add your voice: Should IBM i include open-source RPG tools?

IBM Systems Magazine Subscribe Box Read Now Link Subscribe Now Link iPad App Google Play Store
IBMi News Sign Up Today! Past News Letters