Data Storage Options in Subprocedures

How different types of variable storage impact the behavior of local and global data in subprocedures.

How different types of variable storage impact the behavior

That's exactly right--the LR indicator resets the values of all global fields in the program, but it has no impact on any local fields in subprocedures--even if they're defined as static. Subprocedures don't use and aren't influenced by the RPG cycle. Even though you may feel your current programs don't use the RPG logic cycle because you don't use primary or secondary files, remember that LR is part of the cycle.

How and when would the value of StatCount (a local static field) be reinitialized? The static storage is associated with the job, so, of course, running the program in a new job would yield the same results as the first call we saw earlier. But that's a rather extreme way to accomplish reinitialization of a field's value.

A less extreme way is to reclaim the Activation Group that the program was running in between calls. In our example, the program runs in Activation Group QILE, as specified on the H spec. So issuing a RCLACTGRP QILE (Reclaim Activation Group) command would accomplish it. If we were to run this command between the first and second calls to this program, the results of the two runs would be the same. Another option is to create the program to run in a "self-cleaning" type of Activation Group that will reclaim itself automatically when the program returns to its caller. This can be done by putting *NEW in for the value of the Activation Group instead of QILE.

However, reclaiming an Activation Group, whether explicitly by command or implicitly by type *NEW, is an inefficient way to reinitialize a static field in a subprocedure.

If a real application simply needed to have the value of that static counter initialized on each new call to the program, some simple logic could accomplish this more efficiently. A simple flag (a named indicator would be a good choice) could be defined in the program as a global field. The global flag could either be accessed by the subprocedure directly or passed as a parameter to the subprocedure. The subprocedure logic should reset the value of the local static field if the flag value indicates this is the first call to the subprocedure in the current execution of this program and then modify the parameter value to indicate the subprocedure logic has been run before. This goes against the general rule that subprocedures should avoid accessing global data or updating parameter values, but illustrates a valid reason for making an exception.

If you're a purist and want to avoid updating a parameter, another option would involve an *INZSR (initialization subroutine). The *INZSR could be coded which calls the subprocedure with a special value in a parameter that tells the subprocedure to reinitialize its static variables. In this case the *INZSR routine should either reset the value of the flag after returning from the subprocedure to a value that indicates "no initialization needed" and/or the parameter should be an optional one (made optional by coding Options *NoPass) that isn't used when calling it from the main procedure at all.

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