CL Programming

Common Errors When Calling Programs and Procedures

The following sections describe the errors encountered most frequently in passing values on a CALL command or a CALLPRC command. Some of these errors can be very difficult to debug, and some have serious consequences for program functions.

Date Type Errors Using the CALL Command

The total length of the command string includes the command name, spaces, parameter names, parentheses, contents of variables and apostrophes used. For most commands, the command string initiates the command processing program as expected. However, for some commands some variables may not be passed as expected. For more information on the topic of variables, see "Working with Variables".

When the CALL command is used with the CMD parameter on the SBMJOB command, unexpected results may occur. Syntactically, the CALL command appears the same when used with the CMD parameter as it does when used as the compiler directive for the CALL command. When used with the CMD parameter, the CALL command is converted to a command string that is run at a later time when the batch subsystem initiates it. When the CALL command is used by itself, the CL compiler generates code to perform the call.

Common problems with decimal constants and character variables often occur. In the following cases, the command string is not constructed as needed:

The contents of the character variable is passed as described previously, usually as a quoted character constant with the trailing blanks removed. As a result, the called program may not be passed enough data.

The following methods can be used to correct errors in constructing command strings:

Data Type Errors

When passing a value, the data type (TYPE parameter) must be the same (*CHAR, *DEC, or *LGL) in the calling procedure or program and in the called procedure or program. Errors frequently occur in this area when you attempt to pass a numeric constant. If the numeric constant is enclosed in apostrophes, it is passed as a character string. However, if the constant is not enclosed in apostrophes, it is passed as a packed numeric field with LEN(15 5).

In the following example, a quoted numeric value is passed to a program that expects a decimal value. A decimal data error (escape message MCH1202) occurs when variable &A is referred to in the called program (PGMA):

CALL   PGMA PARM('123')  /* CALLING PROGRAM */
PGM    PARM(&A)  /* PGMA */
DCL    &A *DEC LEN(15 5)  /* DEFAULT LENGTH */
.
.
.
IF (&A *GT 0) THEN(...) /* MCH1202 OCCURS HERE */

In the following example, a decimal value is passed to a program defining a character variable. Generally, this error does not cause run-time failures, but incorrect results are common:

CALL PGMB PARM(12345678)  /* CALLING PROG */
 
PGM PARM(&A)               /* PGMB */
DCL &A *CHAR 8
.
.
.
ENDPGM

Variable &A in PGMB has a value of hex 001234567800000F.

Generally, data can be passed from a logical (*LGL) variable to a character (*CHAR) variable, and vice versa, without error, so long as the value is expressed as '0' or '1'.

Decimal Length and Precision Errors

If a decimal value is passed with an incorrect decimal length and precision (either too long or too short), a decimal data error (MCH1202) occurs when the variable is referred to. In the following examples, the numeric constant is passed as LEN(15 5), but is declared in the called procedure or program as LEN(5 2). Numeric constants are always passed as packed decimal (15 5).

CALL PGMA PARM(123)     /* CALLING PROG */
 
PGM PARM(&A)                  /* PGMA */
DCL &A *DEC (5 2)
.
.
.
IF (&A *GT 0) THEN(...) /* MCH1202 OCCURS HERE */

If a decimal variable had been declared with LEN(5 2) in the calling program or procedure and the value had been passed as a variable instead of as a constant, no error would occur.

If you need to pass a numeric constant to a procedure or program and the procedure or 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')

If a decimal value is passed with the correct length but with the wrong precision (number of decimal positions), the receiving procedure or program interprets the value incorrectly. In the following example, the numeric constant value (with length (15 5)) passed to the procedure is handled as 25124.00.

CALL PGMA PARM(25.124)  /* CALLING PGM */
 
PGM PARM(&A)            /* PGMA */
DCL &A *DEC (15 2)      /* LEN SHOULD BE 15 5*/
.
.
.
ENDPGM

These errors occur when the variable is first referred to, not when it is passed or declared. In the next example, the called program does not refer to the variable, but instead simply places a value (of the detected wrong length) in the variable returned to the calling program. The error is not detected until the variable is returned to the calling program and first referred to. This kind of error can be especially difficult to detect.

PGM           /* PGMA */
DCL &A *DEC (7 2)
CALL PGMB PARM(&A)  /* (7 2) PASSED TO PGMB */
IF (&A *NE 0)  THEN(...)  /* *MCH1202 OCCURS HERE */
.
.
.
ENDPGM

PGM PARM(&A) /* PGMB */
DCL &A *DEC (5 2)        /* WRONG LENGTH */
.
.
.
 CHGVAR &A (&B-&C)      /* VALUE PLACED in &A */
RETURN
When control returns to program PGMA and &A is referred to, the error occurs.

Character Length Errors

If you pass a character value longer than the declared character length of the receiving variable, the receiving procedure or program cannot access the excess length. In the following example, PGMB changes the variable that is passed to it to blanks. Because the variable is declared with LEN(5), only 5 characters are changed to blanks in PGMB, but the remaining characters are still part of the value when referred to in PGMA.

PGM        /* PGMA */
DCL &A *CHAR 10
CHGVAR &A 'ABCDEFGHIJ'
CALL PGMB PARM(&A)           /* PASS to PGMB */
.
.
.
IF (&A *EQ '  ') THEN(...)  /* THIS TEST FAILS */
ENDPGM
 
PGM PARM(&A)     /* PGMB */
DCL &A *CHAR 5   /* THIS LEN ERROR*/
CHGVAR &A '  '   /* 5 POSITIONS ONLY; OTHERS UNAFFECTED */
RETURN

While this kind of error does not cause an escape message, variables handled this way may function differently than expected.

If the value passed to a procedure or program is shorter than its declared length in the receiving procedure or program, there may be more serious consequences. In this case, the value of the variable in the called procedure or program consists of its values as originally passed, and whatever follows that value in storage, up to the length declared in the called procedure or program. The content of this adopted storage cannot be predicted. If the passed value is a variable, it could be followed by other variables or by internal control structures for the procedure or program. If the passed value is a constant, it could be followed in storage by other constants passed on the CALL or CALLPRC command or by internal control structures.

If the receiving procedure or program changes the value, it operates on the original value and on the adopted storage. The immediate effect of this could be to change other variables or constants, or to change internal structures in such a way that the procedure or program fails. Changes to the adopted storage take effect immediately.

In the following example, two 3-character constants are passed to the called program. Character constants are passed with a minimum of 32 characters for the CALL command. (Normally, the value is passed as 3 characters left-adjusted with trailing blanks.) If the receiving program declares the receiving variable to be longer than 32 positions the extra positions use adopted storage of unknown value. For this example, assume that the two constants are adjacent in storage.

CALL PGMA ('ABC' 'DEF')  /* PASSING PROG */
 
PGM  PARM(&A &B) /* PGMA */
DCL  &A *CHAR 50  /* VALUE:ABC+29' '+DEF+15' ' */
DCL  &B *CHAR 10  /* VALUE:DEF+7' ' */
CHGVAR VAR(&A) (' ')  /* THIS ALSO BLANKS &B */
.
.
.
ENDPGM

Values passed as variables behave in exactly the same way.

In the following example, two 3-character constants are passed to the called procedure. Only the number of characters specified are passed for the CALLPRC command. If the receiving program declares the receiving variable to be longer than the length of the passed constant, the extra positions use adopted storage of unknown value.

In the following example, assume the two constants are adjacent in storage.

CALLPRC PRCA ('ABC' 'DEF')  /* PASSING PROG */
 
PGM  PARM(&A &B)       /*  *PRCA  */
DCL  &A *CHAR 5        /*   VALUE:'ABC' + 'DE' */
DCL  &B *CHAR 3        /*   VALUE:'DEF' */
CHGVAR &A ' '          /*   This also blanks the first two bytes of &B */
.
.
.
ENDPGM


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]