Guru: What Is Constant Folding And Why Should I Care About It?
October 18, 2021 Ted Holt
Constant folding is a compiler-optimization technique, whereby the compiler replaces calculations that involve constants with the result values when possible. Constant folding is common in modern compilers, and according to the RPG reference, the RPG compiler uses this technique. (See the documentation of the %div and %rem functions, for example.)
But you and I don’t write compilers. We write business applications. Why then should we care about constant folding? That’s a question worth pondering.
Consider how I used to have to write RPG in the Dark Ages.
C MOVE CUSTNR CUSTSV 50
Here I’m copying the customer account number to a save field, perhaps to check for a control break. What could go wrong with this code? Simply this: If someone increases the size of the customer account number field, CUSTSV will no longer be set to the proper value. What’s worse, the error won’t surface until a customer is assigned account number 100000 or higher, which may be a long time after the program change.
So the wonderful people at IBM decided to let us do this instead:
C *LIKE DEFN CUSTNR CUSTSV C MOVE CUSTNR CUSTSV
One potential source of error is eliminated. I was ecstatic when IBM added the *LIKE DEFN op code to the RPG compiler I was working with at the time.
Nowadays we do the same thing with definition specifications.
dcl-s Cust_Account_Save like(Cust_Account);
Or at least we should. I have seen a lot of code where the programmer could have used the LIKE keyword and didn’t, and I’m not talking about old code.
The LIKE keyword has a second argument that increases or decreases the defined size of a variable. For example:
dcl-s Limit packed (7: 2); dcl-s NewLimit like(Limit: +2);
NewLimit is defined to be nine digits long, two of which are decimal positions.
IBM also gives us three built-in functions that retrieve information about data definitions: %SIZE, %LEN, and %DECPOS. These wonderful functions open up even more possibilities for the compiler to use constant folding. Like the LIKE keyword, they are underused and unappreciated.
Suppose I need to retrieve a decimal number from a character string. The %DEC function carries out such a task easily, but it has to know how to define the resulting value. I could do this:
dcl-s Limit packed (7: 2); Limit = %dec (TextValue: 7: 2);
But this is better:
dcl-s Limit packed (7: 2); dcl-c Length const( %Len (Limit) ); dcl-c DecPos const( %DecPos (Limit) ); Limit = %dec (TextValue: Length: DecPos);
If the definition of LIMIT ever changes, this code takes the change in stride.
It is a quirk, to my way of thinking, that we cannot place the %LEN and %DECPOS function calls directly into the %DEC function, but such is the case. Instead, we have to use the roundabout method of declaring two named constants. I found this out the hard way, even though this behavior is documented in the RPG reference. Evidently I have more important things to do than read manuals.
These functions also come in handy when changing the data type. For example, suppose I want a varchar variable that holds the same amount of data as a fixed-length character field. I can’t use the LIKE keyword, but I can do this:
dcl-s Address char(20); dcl-s AddrMod varchar(%size(Address));
Some compilers are more generous than the RPG compiler when it comes to the use of constants. Suppose I need a variable to be twice as long as a database field. Maybe I’m going to store the hexadecimal representation of the field in the variable. Maybe I’m going to replace each apostrophe with two apostrophes. Some compilers would allow something like this:
dcl-s Address char(20); dcl-s AddrMod char(%len(Address)* 2);
Not so the RPG compiler. Instead, you have to find another way, like this method, which I consider a kludge.
dcl-s Address char(20); dcl-ds AddrMod; *n like(Address); *n like(Address); end-ds AddrMod;
The more we can use the LIKE keyword and the data definition built-in functions, the more chances the compiler has to use constant folding. But why should we care about constant folding? Because we need optimized object code? That’s a good reason, but here’s an even better one: Because constant folding makes programs less likely to break when we modify them. You and I have more important things to do than to search for bugs.