15
Tue, Oct
6 New Articles

What You Can (and Cannot) Do with CL Variables

CL
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Pointer variables, based variables, overlaid variables—do you know all the variable types and the right ways to use them?

 

Editor's Note: This article is an excerpt from the MC Press book Complete CL.

 

Variables are program data that are allowed to change values. They have names and are stored in memory for the duration of the program. Variables are of different types: character, decimal, signed integer, unsigned integer, logical, and pointer.

Declaring Variables

Before you can use a variable in a CL program, you must first define the variable or declare it to the program. Declaring variables must be done at the very beginning of the program, after the PGM statement.

 

A variable name can contain up to 11 characters. The first character must be an ampersand (&), which identifies the rest as a variable name. The second character must be a letter (A to Z) or one of the characters @, #, or $. All characters following the second can be letters, digits (0 to 9), or the characters @, #, $, or _ ("break"). You can use the break character to improve readability. &A, &OUTQ, and &VOL_ID are examples of valid variable names.

 

Examples of invalid variable names would include &NBRDLTPGMMSG, which is too long; &INV%TOTAL, which contains an invalid character; and &4TOTAL, because a digit may not follow the ampersand.

 

Variables are declared to the program with the Declare (dcl) command. Each variable must be declared with a separate dcl command. The dcl command has eight parameters:

 

  •   Var: Receives the name of the variable being declared. Var is a required parameter.
  •   Type: Receives the values *char, *dec, *INT, *UINT, *lgl, or *PTR, depending on whether the variable type is character, decimal, signed integer, unsigned integer, logical, or pointer. This parameter is required, too.
  •   STG: Indicates the storage method; that is, the way the variable is allocated in memory. It's optional.
  •   Len: Indicates the length of the variable. For character, integer, and logical variables, this value indicates the number of bytes to be allocated to the variable. For decimal variables, this value indicates the number of digits the variable should hold. This parameter is optional.
  •   Value: Indicates the initial value for the variable. It's optional too.
  •   BASPTR: Indicates the pointer upon which the variable is based. It's optional.
  •   DEFVAR: Indicates the variable with which this variable shares memory.  This parameter is optional.
  •   ADDRESS: Indicates the initial value of a pointer. It is optional.

 

Note that, for decimal variables, len can contain two numbers: the total length of the variable (how many digits in length), and the number of decimal places. len(5 2), for example, could hold a number as large as 999.99.

 

Because logical variables are always 1 byte long, len(1) is optional. When the len parameter is omitted, the compiler assumes len(32) for character variables, len(15 5) for decimal variables, LEN(4) for integer variables, or len(1) for logical variables.

 

When you omit the len parameter but supply an initial value with the value parameter, the value parameter dictates the length of the variable that will be assumed by the compiler. For example, consider the two cases shown in Figure 1.

 

DCL VAR(&NAME) TYPE(*CHAR) VALUE('QSYSOPR')

DCL VAR(&PI) TYPE(*DEC) VALUE(3.14159265)

 

Figure 1: Examples of declaring the length of the variable based on length of data in the value parameter.

 

When you compile the program that includes the variables shown in Figure 1, &name will have a length of seven (the initial value, qsysopr, contains seven characters). &pi will have a length of (9 8) because its initial value has nine digits (of which eight fall to the right of the decimal point).

 

Character variables can be as long as len(32767). Decimal variables are len(15 9). Logical variables are always len(1). Table 1 summarizes the rules for lengths for various data types.

 

Table 1: Maximum and Default Lengths for Variables

Variable Type 

Maximum Length 

Default Length

TYPE(*CHAR)

LEN(32767)

LEN(32)

TYPE(*DEC)

LEN(15 9)

LEN(15 5)

TYPE(*INT)

LEN(4)

LEN(4)

TYPE(*UINT)

LEN(4)

LEN(4)

TYPE(*LGL)

LEN(1)

LEN(1)

TYPE(*PTR)

n/a

n/a

Note: The only acceptable values for length of both *INT and *UINT are 2 and 4.

 

Although the LEN parameter can be omitted when the default value is suitable, it does make the program harder to read if the programmer does not know the default length. To make your programs easier to read, you should always use the LEN parameter.

 

Where Variables Can Be Used

When you execute commands from the keyboard, you always enter constant values for all parameters. Consider the Display Library (dsplib) command shown in Figure 2.

 

DSPLIB LIB(QGPL) OUTPUT(*PRINT)

 

Figure 2: The DSPLIB command with constant values.

 

As shown in Figure 2, parameter lib is receiving a four-character constant value (qgpl), while parameter output is receiving a six-character constant (*print).

 

When you code a dsplib command in a CL procedure, however, you have the option of using constants or variables in the parameters. Variables add flexibility when such flexibility is needed. If variable &a has a value of qgpl and variable &b has a value of *print, the CL program statement shown in Figure 3 produces the same result as the statement presented in Figure 2.

 

DSPLIB LIB(&A) OUTPUT(&B)

 

Figure 3: The DSPLIB command with variables as parameters.

 

Don't be fooled into believing that variables can do all sorts of magic. If variable &c has the value lib(qgpl) and variable &d has the value OUTPUT(*print), the statement shown in Figure 4 will not produce the same result.

 

DSPLIB &C &D

 

Figure 4: Invalid use of variables in a DSPLIB command.

 

Because it has no way of knowing what values &c and &d will have, the text editors still accept this statement as valid. The source member even compiles correctly because the compiler assumes you are entering the parameters positionally. When the procedure executes, however, it comes to a screeching halt with an error message. The statement is interpreted as shown in Figure 5.

 

DSPLIB LIB('LIB(QGPL)') OUTPUT('OUTPUT(*PRINT)')

 

Figure 5: Results of using the code as shown in Figure 4.

 

Now assume that variable &e has the value dsplib lib(qgpl) output(*print). If you code Figure 6 as a statement, the editor's syntax checker will reject the statement.

 

&E

 

Figure 6: Invalid use of a variable to code a CL command.

 

For the example shown in Figure 6, &E isn't a command; it's a variable. Only commands can be coded in CL programs. Executing commands dynamically requires the use of program qcmdexc.

 

Another example points to an additional source of errors. Suppose you execute from the keyboard the command shown in Figure 7.

 

CHGJOB OUTQ(QGPL/QPRINT) RUNPTY(20) LOG(4 0 *NOLIST)

 

Figure 7: The CHGJOB command with constant values as parameters.

 

If you code this command in a CL program, all parameters can have variables, as shown in Figure 8.

 

CHGJOB OUTQ(&A/&B) RUNPTY(&C) LOG(&D &E &F)

 

Figure 8: The CHGJOB command with variables as parameters.

 

A qualified name such as qgpl/qprint cannot be replaced by only one variable. Two variables, as in &a/&b, take the place of the qualified name. Similarly, a list must be coded with one variable per element of the list, but never with one variable for the entire list. For example, you cannot use the statement shown in Figure 9 to produce the same results as the example shown in Figure 8.

 

CHGJOB OUTQ(&G) RUNPTY(&H) LOG(&I)

 

Figure 9: Invalid use of variables in parameters.

 

The statement is incorrect if &g has the value qgpl/qprint and &i has the value 4 0 *nolist. A single variable can contain only a single value. Outq(&g) would be acceptable if &g had the value qprint only because the command would then use the library list to locate output queue qprint.

Overlaid Variables

Overlaying variables means defining two variables so that they occupy the same memory location. Since the two variables share the same memory, changing one changes the other.

 

To make one variable overlay another, use the STG (storage) and DEFVAR (defined on variable) parameters of the declare command. The STG parameter takes the value *DEFINED. In the DEFVAR parameter, indicate the name of another variable and the first position of that variable that is to share memory. Look at the example in Figure 10.

 

DCL  &QualObj     *CHAR     LEN(20)

DCL  &Object      *CHAR     LEN(10) STG(*DEFINED) DEFVAR(&QualObj  1)

DCL  &Library     *CHAR     LEN(10) STG(*DEFINED) DEFVAR(&QualObj 11)

 

Figure 10: Examples of overlaid variables.

 

There is no difference between the contents of the &Object variable and the first ten positions of &QualObj, because &Object overlays &QualObj at the first position and overlays ten positions. In the same way, &Library is an alternate name for the last ten positions of &QualObj.

Pointer Variables

A pointer variable contains the address of another variable. To define a pointer variable, specify TYPE(*PTR) in the DCL command and do not code the LEN parameter. In Figure 11, the &NextObj variable is a pointer.

 

DCL  VAR(&NextObj)    TYPE(*PTR)

 

Figure 11: A pointer variable holds the address of another variable.

 

Since a pointer variable does not hold data, it is of little value until it is assigned the address of another variable. To assign an address to a pointer in a variable declaration, use the ADDRESS parameter of the DCL command. To assign an address in calculations, use the %ADDRESS function. You may shorten %ADDRESS to %ADDR. Look at the two pointer variables in Figure 12.

 

DCL    VAR(&TopOfList)     TYPE(*PTR)      ADDRESS(&List)

DCL    VAR(&NextObj)       TYPE(*PTR)

DCL    VAR(&Pattern)       TYPE(*CHAR)     LEN(10)

DCL    VAR(&List)          TYPE(*CHAR)     LEN(252)

 

Figure 12: Example of two pointer variables.

 

The &TopOfList variable contains the memory address of the &List variable.  The CHGVAR command assigns the address of &Pattern to the &NextObj pointer variable.

 

To modify the value of a pointer (i.e., to do "pointer arithmetic"), use the %OFFSET (or %OFS) function. In Figure 13, the &NextObj pointer is adjusted to point to the memory address ten bytes after its current position.

 

CHGVAR   VAR(%Offset(&NextObj))   VALUE(%Offset(&NextObj)+10)

 

Figure 13: Use the %OFFSET function for pointer arithmetic.

 

Based Variables

The compiler does not allocate storage to based variables. Instead, the based variable uses a pointer in order to access the storage that has been assigned to another variable. In Figure 14, the &File variable represents two other variables, &SalesHist and &CurrSales, by means of pointer &pFile.

 

DCL VAR(&pFile)     TYPE(*PTR)     

DCL VAR(&File)      TYPE(*CHAR) LEN(20) STG(*BASED) BASPTR(&pFile)

DCL VAR(&SalesHist) TYPE(*CHAR) LEN(10)

DCL VAR(&CurrSales) TYPE(*CHAR) LEN(252)

 

CHGVAR   VAR(&pFile) VALUE(%ADDR(&SalesHist)

/* ... do something using &File ... */

/* ... whatever you do will happen to &SalesHist ... */

CHGVAR   VAR(&pFile) VALUE(%ADDR(&CurrSales)

/* ... do something using &File ... */

/* ... whatever you do will happen to &CurrSales ... */

 

Figure 14: A based variable indirectly accesses other variables.

 

 

TED HOLT

Ted Holt is IT manager of Manufacturing Systems Development for Day-Brite Capri Omega, a manufacturer of lighting fixtures in Tupelo, Mississippi. He has worked in the information processing industry since 1981 and is the author or co-author of seven books. 


MC Press books written by Ted Holt available now on the MC Press Bookstore.

Complete CL: Fifth Edition Complete CL: Fifth Edition
Become a CL guru and fully leverage the abilities of your system.
List Price $79.95

Now On Sale

Complete CL: Sixth Edition Complete CL: Sixth Edition
Now fully updated! Get the master guide to Control Language programming.
List Price $79.95

Now On Sale

IBM i5/iSeries Primer IBM i5/iSeries Primer
Check out the ultimate resource and “must-have” guide for every professional working with the i5/iSeries.
List Price $99.95

Now On Sale

Qshell for iSeries Qshell for iSeries
Check out this Unix-style shell and utilities command interface for OS/400.
List Price $79.95

Now On Sale

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: