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

If your predicted answers were different from these results, let's look at why.

First of all, notice that field AutoCount always contains a value of 1. That's because local subprocedure fields, by default, use automatic (sometimes called dynamic) storage. Such automatic storage only exists for the duration of the running of the subprocedure. It is allocated when the subprocedure is called and is freed when the subprocedure returns to its caller (in this case, to the main procedure). Therefore on the second and third calls, this field with automatic storage (AutoCount) begins anew with an initial value of 0 on each call at the beginning of the subprocedure logic. This automatic storage phenomenon explains something that many developers have asked us about--"why can't I see the values of my subprocedure fields in a debug session?" If you're not currently executing the subprocedure, the storage doesn't actually exist.

Secondly, notice that StatCount is defined with the D spec keyword "Static." This changes the storage type for the field to be static, rather than the default of automatic. Storage for static fields remains in place between calls to the subprocedure. Therefore, the value of StatCount increases by 1 on each subsequent call.

The Static keyword is only available to be specified for local fields in subprocedures because all global fields (i.e., those defined in the main procedure, such as GlobalCount) use static storage, just as they have done in previous versions of the RPG language. Therefore, you see that our global field, GlobalCount, also increases by 1 on each call, just as the StatCount field that was declared as local did.

So far, so good. With this simple example, we have illustrated the difference in behaviour between fields using automatic (or dynamic) storage and static storage. There is one more twist to the story. We asked you earlier to predict not only the results of the first call but also the second call to the program in the same job. Even developers who know about local, global, static and automatic often get this second one wrong. Here are the results of the second call:

DSPLY Call to Main Pgm Begins Here
DSPLY > Call 1 to Subprocedure
DSPLY >> AutoCount=1, StatCount=4, GlobalCount=1
DSPLY > Call 2 to Subprocedure
DSPLY >> AutoCount=1, StatCount=5, GlobalCount=2
DSPLY > Call 3 to Subprocedure
DSPLY >> AutoCount=1, StatCount=6, GlobalCount=3

Our earlier explanation indicated that StatCount and GlobalCount contained the same values because they were both in static storage. So why do they have different values now? This is caused by the last line of logic in the main procedure of the program (*INLR = *On;). Because we set the LR indicator on, it (hopefully) doesn't surprise anyone that GlobalCount was reset back to its initial value (0) for the second call. Because the storage for AutoCount had disappeared before LR was set on, it's unaffected and behaves the same as before. But StatCount seems to have been oblivious to the fact that the LR indicator was set on and the program ended.

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