Midware Ltd.



Sign-up for e-mail notifications

Take our weekly poll

Dow Jones Intraday

Nasdaq Intraday



One of the first differences you'll notice when coding RPG IV programs (aside from the mixed case entry) is that the C-spec layout has shifted significantly.  This is primarily to allow for longer field names and support free-form expressions.  There are two primary C-spec layouts - one for fixed format lines and one for free-format expressions.

Fixed format:

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10

Free format:

*.. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+... 10

Note that by default, PDM will position to column 6 (instead of column 1 for RPG III code).  If your shop uses columns 1 to 5 for comments or begin/end tags, you should be aware of this as most programmers will not see these positions and may inadvertently copy comments erroneously.

Also note that there is only one left-hand conditioning indicator.  Left-hand conditioning indicators were used extensively in RPG II - not as much in RPG III.  If you use CVTRPGSRC to convert your RPG III code to RPG IV and the original code used conditioning indicators liberally, the result can be pretty ugly!  It is strongly recommended that you convert conditioning indicators to IF statements.  Some third-party RPG IV conversion programs will do this for you automatically.

Factor 1 and factor 2 now each have room for 14-byte field names.  Take advantage of this by naming internal fields less cryptically.  For example, if you have a field that totals net sales by account, instead of naming it NTSLAC, you may want to name it something like @NetSlsByAcct.

Note:  Although you can still define fields on the fly by supplying a length, it is considered good structure to define all internal fields as stand-alone fields in D-specs.

Operation codes have also be extended.  In RPG III, there was a limitation of 5-characters, which forced some opcodes to be abbreviated (for example, BITOF, DELET, and LOKUP).  RPG IV has expanded the length of opcodes and name some of the RPG III opcodes more logically (BITOFF, DELETE, and LOOKUP).  The operation extender that was in position 53 in RPG III has been moved next to the opcode itself (the operation extender is used much more extensively in RPG IV).

Extended factor 2

There are a number of opcodes new to RPG IV that take advantage of the new extended factor 2 layout.  The extended factor 2 area allows you to enter free-format expressions and take advantage of RPG's built-in-functions.

All RPG III opcodes that include a comparison operator (for example, IFEQ, DOWLT, etc) can be written in RPG IV using the free-form extended factor 2 format.  For example:

C     *in99         ifeq      *off
C     cust#         andne     @SaveCust#

can be re-written as:

C                   if        *in99 = *off and
C                             cust# <> @SaveCust#

While both statements function identically, the free-format version can be much more readable, especially with complex evaluations.  Note that factor 1 is not used, and the ANDxx or ORxx operation codes are not needed to continue an expression on a new line.  Parenthesis may be used to prioritize expression.  Evaluations in the innermost parenthesis pair are always performed first.

C                   if        (*in99 = *off and
C                              cust# <> @SaveCust#) or
C                             (cust# = *blanks or
C                              cust# = '00000')     or
C                             (*in03 = *on)

Free-format expressions may also include calculations:

C                   if         x = y + z and 
C                             (a = (b * c) - d) or 
C                              (cust# = *blanks or
C                              cust# = '00000')     or
C                             (*in03 = *on)

The following operation codes allow use of extended factor 2:

RPG IV RPG III equivalent
IF IFxx (IFEQ, IFLE, etc.)
WHEN (used in a SELECT group) WHxx
EVAL (none)
EVALR (new to V4R4) (none)
FOR (new to V4R4) (none)

EVAL/EVALR operations

The EVAL opcode (new to RPG IV) allows you to assign values to variables using a free-format expression.

C                   eval      x = y + z
C                   eval      @String = "Midware Services"

EVAL may be used with any data types - however the right side of the equation must evaluate to the same type as the variable on the left side of the equation.  For example EVAL may not be used to assign a numeric field to a character string.  (Built-in-functions may be used to convert data types however)

EVAL may be thought of as combining the functionality of the Z-ADD, MOVEL, ADD, SUB, MULT, and DIV operation codes into a single statement.  Previous functionality that used to be only possible with multiple lines of code may now be combined into a single statement:

D @DailyRate      S              4F

C     @WeeklyRate   div      7              @DailyRate
C     @NumberDays   mult     @DailyRate     @InvoiceAmt

may be re-written as:

C                   eval      @InvoiceAmt = (@WeeklyRate / 7) *
C                                @NumberDays

Note that in the first example, we needed to define @DailyRate as an interim field.  We defined it as a floating point (single precision) because we don't know how the divide will truncate.  An interim field is not required in the EVAL statement.

If the EVAL operation is used on character strings of unequal length, it will truncate the same as the MOVEL opcode.  The EVALR opcode (new to V4R4) may be used to simulate the MOVE opcode:

D X               S              2A
D Y               S              4A
D Z               S              3A   inz('ABC')

C                   eval     X = Z
C*   X = "AB"
C                   eval     Y = Z
C*   Y = "ABC "
C                   evalr    X = Z
C*   X = "BC"
C                   evalr    Y = Z
C*   Y = " ABC"

Converting to EVAL

Once you get comfortable with the EVAL statement, you may want to convert your existing code to take advantage of the benefits.  Some third-party RPG III conversion programs will even do this conversion for you.  There are several gotcha's you should be aware of before you do this however.

Eval vs. EvalR:  Keep in mind that for character strings, EVAL is equivalent to MOVEL, and EVALR is equivalent to MOVE.  EVALR is also not available until V4R4.  

Numeric overflow:  The traditional numeric handling opcodes (Z-ADD, MULT, etc.) will automatically truncate significant digits if the result field is not long enough.  The EVAL opcode, however, will produce a run-time machine error.  Unfortunatly, the only way to handle this gracefully at the present time is to code a *PSSR error handling subroutine.

Interim calculated values:  Converting several calculations into a single EVAL statement may not always have the expected result.  Take the following example:

C     X             div      Y              @Temp
C     @Temp         mult     3.14159        Z

C                   eval     Z = (X / Y) * 3.14159

Although it looks like the two methods are the same, you may get slightly different results depending on how @Temp is defined.  In the EVAL statement, a floating point value is used for the interim result.  Truncation may occur however in the first DIV statement causing different results.

Note:  Unless truncation is desired, the EVAL statement will produce the more accurate result.  This may cause unexpected differences in parallel testing however.

For a complete listing of RPG IV operation codes as of V4R5, see IBM's online documentation.

  Back to D-specs Next to Date and Time support 
Home Feedback Contents Search

Send mail to midware@midwareservices.com with questions or comments about this web site.
Copyright 2000 Midware, Ltd.

Last Modified:  August 10, 2000