Wednesday, April 30, 2008

Call of the Prototype:

A lot of RPG programmers are under the misconception that the CALLP operation means Call Procedure. That is because most of them come across it when they start using subprocedures. But CALLP means Call a Prototyped Procedure or Program, and it can be used in place of the CALL operation, as well as CALLB.
What's wrong with CALL and PARM?
In RPG all parameters are passed by reference. That means a pointer to the parameter is passed, not the actual value of the parameter. That, in turn, means both the passed and receiving parameter fields share the same memory location, and that is where the potential problem lies.
Figure 1 shows the code of a calling program. It calls PGMB passing Parm1, a 10 character field, as a parameter.
D TestParm DS
D Parm1 10 Inz('XXXXXXXXXX')
D Parm2 10 Inz('YYYYYYYYYY')

C Call 'PGMB'
C Parm Parm1
Figure 1: A program call with a parameter field in a data structure
Figure 2 shows the code of the called program. It has an incorrect length of 15 for Parm1.
Will the compiler tell us that it is invalid? No.
Will the program fail at run time? No.
What will happen? When control returns to the calling program, Parm1 will have a value of 'ZZZZZZZZZZ' and Parm2 will have a value of 'ZZZZZYYYYY'.
When the compiler sees a CALLP operation, it will validate to ensure that all the parameters are correct. But how does it know that the parameters are correct? You provide a prototype. A prototype is the format, or the template, or the rules, for the call operation. It is not a parameter list.
Prototypes are defined on the D specifications, as shown in Figure 3. The format of a prototype is very similar to a data structure, except that the type is PR as opposed to DS. You can provide your own name for the CALLP (PromptProduct). The EXTPGM keyword indicates that this is the equivalent of a CALL operation, and it identifies the name of the called program (PRP01R). The names of the subfields in the prototype are irrelevant, what are important are the number of subfields (i.e. parameters) and the definition of each. In the example in Figure 3 the compiler will ensure that two parameters are passed, that Parm1 is a 30 character field and that Parm2 is a 1 character field.
D PromptProduct PR ExtPgm('PRP001R')
D FirstParm 30
D SecondParm 1

C CallP PromptProduct(Parm1:Parm2)

Other features of prototype like ‘CONST’, ‘*OMIT’, ‘*NOPASS’ easy the coding process.

No comments: