IBM Support

Passing Parameters Between Programs and Procedures

Troubleshooting


Problem

This document provides information on passing parameters between programs and procedures.

Resolving The Problem

The following is taken from the OS/400 CL Programming Manual:

3.4 Passing Parameters between Programs and Procedures

When you pass control to another program or procedure, you can also pass information to it for modification or use within the receiving program or procedure. See the discussion of this under "Using the CALL Command" in topic 3.4.1. You can specify the information to be passed on the PARM parameter on the CALL command or the CALLPRC command. The characteristics and requirements for these commands are slightly different.

For instance, if PROGA contains the following command:

CALL PROGB PARM(&AREA)

then it calls PROGB and passes the value of &AREA to it. PROGB must start with the PGM command, which also must specify the parameter it is to receive:

PGM PARM(&AREA) /* PROGB */


   PROGA                                                                      
  +---------------------------------------+ VALUE                            
  │ PGM                 +-----------------+------------+                    
  │ DCL  &AREA *CHAR 10 │                 │            │                    

   │                     │                 │  PROGB     V                    
  │                     │                 │  +----------------------------+  
  │                     │                 │  │ PGM PARM(&AREA) /*PROG B*/ │  
  │ CALL PROGB PARM(&AREA)                │  │ DCL &AREA *CHAR 10         │  
  │                                       │  │                            │  
  │                                       │  │                            │  
  │                                       │  │                            │  
  │ ENDPGM                                │  │ ENDPGM                     │  
  +---------------------------------------+  +----------------------------+  
  --------------->                                                          
  CONTROL                                                                    



For the CALL command or the CALLPRC command, you must specify the parameters passed on the PARM parameter, and you must specify them on the PARM parameter of the PGM command in the receiving program or procedure. Because parameters are passed by position, not name, the position of the value passed in the CALL command or the CALLPRC command must be the same as its position on the receiving PGM command. For example, if PROGA contains the following command:

CALL PROGB PARM(&A &B &C ABC)

it passes three variables and a character string, and if PROGB starts with:

PGM PARM(&C &B &A &D) /*PROGB*/

then the value of &A in PROGA is used for &C in PROGB, and so on; &D in PROGB is ABC. The order of the DCL statements in PROGB is unimportant. Only the order in which the parameters are specified on the PGM statement determines what variables are passed.

In addition to the position of the parameters, you must pay careful attention to their length and type. Parameters listed in the receiving procedure or program must be declared as the same length and type as they are in the calling procedure or program. Decimal constants are always passed with a length of (15 5).

When you use the CALLPRC command and pass character string constants, you must specify the exact number of bytes, and pass exactly that number. The called procedure can use the information in the operational descriptor to determine the exact number of bytes passed. The operational descriptor can be access using the CEEDOD API. See the System API Reference for information on the API.

When you use the CALL command, character string constants of 32 bytes or less are always passed with a length of 32 bytes. If the string is longer than 32, you must specify the exact number of bytes, and pass exactly that number.

For instance, if you wrote a procedure or program receiving a value &VAR1, like this:

PGM PARM(&VAR1)  /*PGMA*/                                                
    DCL VAR1 *CHAR LEN(36)                                                  
    .                                                                        
    .                                                                        
    .                                                                        
    ENDPGM                      
                                             

the CALL command or CALLPRC command must specify 36 characters:

CALLPRC PGMA(ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJ)

The following example specifies the default lengths:
PGM PARM(&P1 &P2)
DCL VAR(&P1) TYPE(*CHAR) LEN(32)
DCL VAR(&P2) TYPE(*DEC) LEN(15 5)
IF (&P1 *EQ DATA) THEN(CALL MYPROG &P2)
ENDPGM                      
 
To call this program, you could specify:

CALL PROG (DATA 136)

The character string DATA is passed to &P1; the decimal value 136 is passed to &P2.

Referring to locally defined variables incurs less overhead than referring to passed variables. Therefore, if the called procedure or program frequently refers to passed variables, performance can be improved by copying the passed values into a local variable and referring to the locally defined value rather than the passed value.

3.4.1 Using the CALL Command
3.4.2 Common Errors When Calling Programs and Procedures


3.4.1 Using the CALL Command


When the CALL command is issued by a CL procedure, each parameter value passed to the called program can be a character string constant, a numeric constant, a logical constant, or a CL variable. A maximum of 40 parameters can be passed to the called program. The values of the parameters are passed in the order in which they appear on the CALL command, and this must match the order in which they appear in the parameter list of the called program. The names of the variables passed do not have to be the same as the names on the receiving parameter list. The names of the variables receiving the values in the called program must be declared to the called program, but the order of the declare commands is not important. No storage in the called program is associated with the variables it receives. Instead, when a variable is passed, the storage for the variable is in the program in which it was originally declared. Variables are passed by address. When a constant is passed, a copy of the constant is made in the calling program and that copy is passed to the called program.

The result is that when a variable is passed, the called program can change the value of the variable, and the change is reflected in the calling program. The new value does not have to be returned to the calling program for later use; it is already there. Thus no special coding is needed for a variable that is to be returned to the calling program. When a constant is passed, and its value is changed by the called program, the changed value is not known to the calling program. Therefore, if the calling program calls the same program again, it reinitializes the values of constants, but not of variables.

An exception to the previous description is when the CALL command is used to call a C/400 program. In this case, the CALL command parameters (both constants and variables) are converted to null terminated strings (ASCI C standards requirement) and are passed by value. See the C/400 Users Guide, SC09-1347, for more information.

If a CL program might be called using a CALL command that has not been compiled (an interactive CALL command or through the SBMJOB command), the decimal parameters (*DEC) should be declared with LEN(15 5), and the character parameters (*CHAR) should be declared LEN(32) or less in the receiving program.

A CALL command that is not in a CL procedure or program cannot pass variables as arguments. When the CALL command is used with command parameters defined as *CMDSTR, the contents of any variables specified on the PARMS parameter are converted to constants. The command (CMD) parameters on the submit job (SBMJOB) command, add job (ADDJOBSCDE) command, or change job (CHGJOBSCDE) command are examples. For more information on how parameters are passed when using an interactive CALL command, see the description of the CALL command in the CL Reference book.

Parameters can be passed and received as follows:

o Character string constants of 32 bytes or less are always passed with a length of 32 bytes (padded on the right with blanks). If a character constant is longer than 32 bytes, the entire length of the constant is passed. If the parameter is defined to contain more than 32 bytes, the CALL command must pass a constant containing exactly that number of bytes. Constants longer than 32 characters are not padded to the length expected by the receiving program.

The receiving program can receive less than the number of bytes passed. For example, if a program specifies that 4 characters are to be received and ABCDEF is passed (padded with blanks in 26 positions), only ABCD are accepted and used by the program.

If the receiving program receives more than the number of bytes passed, the results may be unexpected. Numeric values passed as characters must be enclosed in apostrophes.

The system counts the characters on a SBMJOB command. The character following the opening parenthesis is the first character counted. The command name, parameter names, spaces, variable lengths, and apostrophes are counted as characters. If you use character variables in the command string, apostrophes are added and counted when the value is substituted.

o Decimal constants are passed in packed form and with a length of LEN(15 5), where the value is 15 digits long, of which 5 digits are decimal positions. Thus, if a parameter of 12345 is passed, the receiving program must declare the decimal field with a length of LEN(15 5); the parameter is received as 12345.00000.

If you need to pass a numeric constant to a program and the program is expecting a value with a length and precision other than 15 5, the constant can be coded in hexadecimal format. The following CALL command shows how to pass the value 25.5 to a program variable that is declared as LEN(5 2):

CALL PGMA PARM(X'02550F')

o Logical constants are passed with a length of 32 bytes. The logical value 0 or 1 is in the first byte, and the remaining bytes are blank. If a value other than 0 or 1 is passed to a program that expects a logical value, the results may be unexpected.

o A floating point literal or floating point special value (*NAN, *INF, or *NEGINF) is passed as a double precision value, which occupies 8 bytes. Although a CL program cannot process floating point numbers, it can receive a floating point value into a character variable and pass that variable to an HLL program that can process floating point values.

o A variable can be passed if the call is made from a CL procedure or program, in which case the receiving program must declare the field to match the variable defined in the calling CL procedure or program. For example, if a CL procedure or program defines a decimal variable named &CHKNUM as LEN(5 0), the receiving program must declare the field as packed with 5 digits total, with no decimal positions. When a CALL command is run in batch mode using the SBMJOB command in a CL procedure or program, variables passed as arguments are treated as constants.

o If either a decimal constant or a program variable can be passed to the called program, the parameter should be defined as LEN(15 5), and any calling program must adhere to that definition. If the type, number, order, and length of the parameters do not match between the calling and receiving programs (other than the length exception noted previously for character constants), results cannot be predicted.

o The value *N cannot be used to specify a null value because a null value cannot be passed to another program.

In the following example, program A passes six parameters: one logical constant, three variables, one character constant, and one numeric constant.

  PGM /* PROGRAM A */
    DCL VAR(&B) TYPE(*CHAR)
    DCL VAR(&C) TYPE(*DEC) LEN(15 5) VALUE(13.529)
    DCL VAR(&D) TYPE(*CHAR) VALUE('1234.56')
    CHGVAR VAR(&B) VALUE(ABCDEF)
    CALL PGM(B) PARM('1' &B &C &D XYZ 2)  /* Note blanks between parms */
    .
    .
    .
    ENDPGM

    PGM PARM(&A &B &C &W &V &U) /* PROGRAM B */
    DCL VAR(&A) TYPE(*LGL)

     DCL VAR(&B) TYPE(*CHAR) LEN(4)
    DCL VAR(&C) TYPE(*DEC)
               /* Default length (15 5) matches DCL LEN in program A */
    DCL VAR(&W) TYPE(*CHAR)
    DCL VAR(&V) TYPE(*CHAR)
    DCL VAR(&U) TYPE(*DEC)
    .
    .
    .
    ENDPGM


Note: If the fifth parameter passed to PGMB was 456 instead of XYZ and was intended as alphanumeric data, the value would have been specified as '456' in the parameter.

The logical constant '1' does not have to be declared in the calling program. It is declared as type logical and named &A in program B.

Because no length is specified on the DCL command for &B, the default length, which is 32 characters, is passed. Only 6 characters of &B are specified (ABCDEF). Because &B is declared with only 4 characters in program B, only those 4 characters are received. If they are changed in program B, those 4 positions for &B will also be changed in program A for the remainder of this call.

The length (LEN) parameter must be specified for &C in program A. If it were not specified, the length would default to the specified value's length, which would be incompatible with the default length expected in program B. &C has a value of 13.52900.

&W in program B (&D in program A) is received as a character because it is declared as a character. Apostrophes are not necessary to indicate a string if TYPE is *CHAR. In program A, the length defaults to the value's length of 7 (the decimal point is considered a position in a character string). Program B expects a length of 32. The first 7 characters are passed, but the contents past the position 7 cannot be predicted.

The variable &V is a character string XYZ, padded with blanks on the right. The variable &U is numeric data, 2.00000.

For more information on the default lengths in the DCL commands, see the DCL command in the CL Reference book.

[{"Type":"MASTER","Line of Business":{"code":"LOB57","label":"Power"},"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SWG60","label":"IBM i"},"Platform":[{"code":"PF012","label":"IBM i"}],"Version":"6.1.0"}]

Historical Number

13922750

Document Information

Modified date:
18 December 2019

UID

nas8N1018238