A CL variable is declared once with DCL and changed afterward with CHGVAR (or implicitly, by RCVF, RTVJOBA, and similar retrieve commands). This page is the lookup for the types DCL supports and the rules CHGVAR follows when it assigns a value. For the surrounding program skeleton, see CL Program Structure: PGM, DCL, and ENDPGM.
The Six Variable Types
DCL VAR(&name) TYPE(*DEC | *CHAR | *LGL | *INT | *UINT | *PTR)
Verification level: IBM DOC CHECKED, against the IBM i 7.5 DCL command reference.
| Type | Holds | Default length | Maximum |
|---|---|---|---|
*CHAR | Character string | 32 bytes | 32,767 bytes |
*DEC | Packed decimal number | 15 digits, 5 decimal positions | 15 digits, up to 9 decimal positions |
*LGL | Logical, '1' or '0' | 1 byte | 1 byte |
*INT | Signed binary integer | 4 bytes | 8 bytes (ILE CL only; 4 bytes in OPM CL) |
*UINT | Unsigned binary integer | 4 bytes | 8 bytes (ILE CL only; 4 bytes in OPM CL) |
*PTR | A 16-byte address | 16 bytes, fixed | Not applicable — LEN cannot be specified |
Integer lengths (*INT/*UINT) must be 2, 4, or 8; a length of 8 is allowed only in ILE CL procedures, not in original-program-model (OPM) CL programs. If LEN is omitted but VALUE is given for *CHAR or *DEC, the length is taken from the initial value. If VALUE is omitted entirely, *CHAR starts as blanks, numeric types start at zero, and *LGL starts at '0'.
Examples:
DCL VAR(&NAME) TYPE(*CHAR) LEN(30)
DCL VAR(&AMOUNT) TYPE(*DEC) LEN(9 2)
DCL VAR(&FOUND) TYPE(*LGL) VALUE('0')
DCL VAR(&COUNT) TYPE(*INT) LEN(4)
Verification level: IBM DOC CHECKED.
*PTR, *BASED, and *DEFINED storage are used for pointer-based variables (common in API work) and are outside the scope of this reference; the IBM i CL overview covers them under “Declaring variables.”
CHGVAR Syntax
CHGVAR VAR(variable) VALUE(value)
Verification level: IBM DOC CHECKED, against the IBM i 7.5 CHGVAR command reference.
Both VAR and VALUE are required and positional, so the shorthand form is common:
CHGVAR &A &B
VAR can also reference a substring (%SST/%SUBSTRING) or a binary field (%BIN/%BINARY) with a start position and length, letting CHGVAR update part of a character variable without touching the rest. VALUE accepts a constant, another variable, or an expression built from arithmetic operators, *CAT, or built-in functions.
*DEC Arithmetic
Numeric expressions are evaluated directly in VALUE:
DCL VAR(&COUNT) TYPE(*DEC) LEN(5 0) VALUE(0)
CHGVAR VAR(&COUNT) VALUE(&COUNT + 1)
Verification level: IBM DOC CHECKED.
Points that cause real-world bugs:
- A
*DECvalue with too many integer or fractional digits than the variable’sLENallows is a runtime error, not a silent truncation — unlike character assignment, which pads or truncates quietly. SizeLENgenerously for accumulators used in loops. - Decimal-to-character assignment zero-pads on the left and puts a minus sign, if any, in the leftmost position; positive values get no sign character. The receiving
*CHARvariable must be long enough to hold the sign and any decimal point, or the assignment fails. - Character-to-decimal assignment accepts only digits, a decimal point, and a leading sign immediately before the first digit. Anything else in the source string is an error, not a silent conversion.
*DECconstants inVALUEmay include a decimal point (period or comma, depending on job settings) and a sign; without a decimal point, the value is treated as a whole number.
String Concatenation with *CAT
CL has no + operator for strings; use *CAT:
DCL VAR(&FIRST) TYPE(*CHAR) LEN(10) VALUE('AB')
DCL VAR(&LAST) TYPE(*CHAR) LEN(10) VALUE('CD')
DCL VAR(&FULL) TYPE(*CHAR) LEN(20)
CHGVAR VAR(&FULL) VALUE(&FIRST *CAT &LAST)
Verification level: IBM DOC CHECKED.
Gotchas with *CAT:
*CATconcatenates the full declared length of each operand, trailing blanks included, unless you trim them first with%TRIM,%TRIMR, or%TRIML. Concatenating twoLEN(10)variables that each hold two characters produces a 20-character result padded with 16 blanks in the middle, not'ABCD'.- Character constants with special characters, embedded blanks, or that look like numbers need apostrophes in
VALUE; an unquoted token is interpreted following CL’s usual naming/constant rules, which can silently produce the wrong value for a string that happens to parse as something else. - Shorter assigned values are padded with blanks on the right; longer values are truncated — there is no error for either case with
*CHAR, which is the opposite of the hard error you get oversizing a*DECvalue.
Logical and Hex Values
DCL VAR(&OK) TYPE(*LGL) VALUE('0')
CHGVAR VAR(&OK) VALUE('1')
Verification level: IBM DOC CHECKED.
*LGL variables are set with '1' or '0' in apostrophes; %SWITCH can set one from an 8-character job switch mask. Decimal and character values can also use hexadecimal notation, X'...'; CL does not validity-check a character hex string’s contents, so a malformed hex literal can be assigned without an immediate error.
Common Mistakes
- Sizing a
*DECaccumulator too small for a loop that keeps adding to it. It fails at runtime, often well into a long-running job, rather than at compile time. - Forgetting that
*CATkeeps trailing blanks. Trim operands explicitly with%TRIMR/%TRIMwhen concatenating fixed-length fields. - Treating
*CHARtruncation as an error. It isn’t — a value that’s too long for the target variable is silently cut off, which can hide a bug for a long time. - Omitting apostrophes around a character constant that looks numeric or contains special characters.
Summary
DCL VAR() TYPE()supports*CHAR,*DEC,*LGL,*INT,*UINT, and*PTR, each with its own default and maximum length.CHGVAR VAR() VALUE()assigns constants, variables, or expressions; the shorthandCHGVAR &A &Bworks identically.*DECoverflow is a hard runtime error;*CHARoverflow truncates silently — size variables with both behaviors in mind.- Concatenate strings with
*CAT, trimming trailing blanks first if the operands are fixed-length.
Sources: IBM i 7.5 DCL command and IBM i 7.5 CHGVAR command. All examples are documentation-checked only; none were compiled or run.
Continue with CL Program Structure: PGM, DCL, and ENDPGM for the surrounding program skeleton, or Reading Database Files in CL with DCLF and RCVF for file-driven variables.