Defined variables make it easy to manage complex data structures in CL by eliminating the need to substring values out of a large variable.
Defined variables can be used to map different parts of the defined on variable or the same part of a given variable in different ways.
In the following example, the variables &LIBNAME will always be equal to the first 10 bytes of &OBJECT. Using the defined variable &LIBNAME will improves the readability of the code and makes it easier to work with. The variable &OBJECT provides the storage for the &LIBNAME and &OBJNAME variables.
PGM DCL &OBJECT *CHAR 20 DCL &LIBNAME *CHAR 10 STG(*DEFINED) DEFVAR(&OBJECT) DCL &OBJNAME *CHAR 10 STG(*DEFINED) DEFVAR(&OBJECT 11) : IF COND(%SST(&OBJECT 11 10) *EQ &OBJNAME) + THEN(...)) : ENDPGM
You can also make the same storage with multiple definitions. In this example, the variables &BINLEN and &CHARLEN both refer to the same 4 bytes of variable &STRUCT. The program can then use the definition that best suits its requirements.
PGM DCL &STRUCT *CHAR 50 DCL &BINLEN *INT 4 STG(*DEFINED) DEFVAR(&STRUCT) DCL &CHARLEN *CHAR 4 STG(*DEFINED) DEFVAR(&STRUCT) : ENDPGM
This example shows how a defined variable can be used to change values in a variable. This example also makes use of the %OFFSET built-in function and a based variable to navigate the library list. This is not the optimal way to do message substation but illustrates some of the capabilities of defined variables.
PGM DCL &MESSAGE *CHAR 25 VALUE('LIBRARY NNN IS XXXXXXXXXX') DCL &SEQUENCE *CHAR 3 STG(*DEFINED) DEFVAR(&MESSAGE 9) DCL &MSGLIBN *CHAR 10 STG(*DEFINED) DEFVAR(&MESSAGE 16) DCL &COUNTER *INT 2 DCL &LIBL *CHAR 165 DCL &PTR *PTR ADDRESS(&LIBL) DCL &LIBLNAME *CHAR 10 STG(*BASED) BASPTR(&PTR) : RTVJOBA SYSLIBL(&LIBL) CHGVAR &COUNTER 0 DOFOR &COUNTER FROM(1) TO(15) IF (&LIBLNAME *EQ ' ') THEN(LEAVE) CHGVAR &SEQUENCE &COUNTER CHGVAR &MSGLIBN &LIBLNAME SNDPGMMSG MSGID(CPF9898) MSGF(QSYS/QCPFMSG) MSGDTA(&MESSAGE) CHGVAR %OFS(&PTR) (%OFS(&PTR) + 11) ENDDO : ENDPGM