COBOL Programming Guide
COBOL Programming Guide
Programming Guide
Version 2 Release 2
SC26-9049-05
COBOL for OS/390 & VM
Programming Guide
Version 2 Release 2
SC26-9049-05
Note!
Before using this information and the product it supports, be sure to read the general information under “Notices” on
page 609.
iv Programming Guide
Example: password protection for a VSAM Sort special registers . . . . . . . . . . 184
indexed file . . . . . . . . . . . . . 152 Changing DFSORT defaults with control
Working with VSAM data sets under OS/390 and statements . . . . . . . . . . . . . 185
OS/390 UNIX . . . . . . . . . . . . . 152 Allocating storage for sort or merge operations 186
Defining VSAM files under OS/390 . . . . . 153 Using checkpoint/restart with DFSORT under
Creating alternate indexes . . . . . . . . 154 OS/390 . . . . . . . . . . . . . . . 186
Allocating VSAM files . . . . . . . . . 156 Sorting under CICS . . . . . . . . . . . 187
Sharing VSAM files through RLS . . . . . . 157 CICS SORT application restrictions . . . . . 187
Defining VSAM data sets under CMS . . . . . 158
Improving VSAM performance . . . . . . . 159 Chapter 12. Handling errors . . . . . 189
Requesting dumps . . . . . . . . . . . 189
Chapter 10. Processing line-sequential Creating a formatted dump. . . . . . . . 189
files . . . . . . . . . . . . . . . 163 Creating a system dump . . . . . . . . 190
Defining line-sequential files and records in Handling errors in joining and splitting strings . . 190
COBOL . . . . . . . . . . . . . . . 163 Handling errors in arithmetic operations . . . . 191
Allowable control characters . . . . . . . 164 Example: checking for division by zero . . . . 191
Describing the structure of a line-sequential file 164 Handling errors in input and output operations 191
Defining and allocating line-sequential files . . . 165 Using the end-of-file condition (AT END) . . . 193
Coding input-output statements for line-sequential Coding ERROR declaratives . . . . . . . 194
files . . . . . . . . . . . . . . . . 165 Using file status keys . . . . . . . . . . 194
Opening line-sequential files . . . . . . . 166 Example: file status key . . . . . . . . . 195
Reading records from line-sequential files . . . 166 Using VSAM return codes (VSAM files only) 196
Adding records to line-sequential files . . . . 167 Example: checking VSAM status codes . . . . 196
Closing line-sequential files. . . . . . . . 167 Coding INVALID KEY phrases . . . . . . 198
Handling errors in line-sequential files . . . . . 168 Example: FILE STATUS and INVALID KEY . . 198
Handling errors when calling programs . . . . 199
Chapter 11. Sorting and merging files 169 Writing routines for handling errors . . . . . . 199
Sort and merge process . . . . . . . . . . 170
Describing the sort or merge file . . . . . . . 170 Part 2. Compiling and debugging
Describing the input to sorting or merging . . . 171 your program . . . . . . . . . . 201
Example: describing sort and input files for
SORT . . . . . . . . . . . . . . . 171
Coding the input procedure . . . . . . . . 172
Chapter 13. Compiling under OS/390 203
Describing the output from sorting or merging . . 173 Compiling with JCL . . . . . . . . . . . 203
Coding the output procedure . . . . . . . . 173 Using a cataloged procedure . . . . . . . 204
Coding considerations when using DFSORT on Writing JCL to compile programs. . . . . . 213
OS/390 . . . . . . . . . . . . . . 174 Compiling under TSO . . . . . . . . . . 215
Example: coding the output procedure when Example: ALLOCATE and CALL for compiling
using DFSORT . . . . . . . . . . . . 174 under TSO . . . . . . . . . . . . . 215
Restrictions on input and output procedures . . . 175 Example: CLIST for compiling under TSO . . . 216
Defining sort and merge data sets under OS/390 175 Starting the compiler from an assembler program 216
Defining sort and merge files under CMS . . . . 176 Defining compiler input and output . . . . . . 218
Sorting variable-length records . . . . . . . 176 Data sets used by the compiler under OS/390 218
Requesting the sort or merge . . . . . . . . 177 Defining the source code data set (SYSIN) . . . 220
Setting sort or merge criteria . . . . . . . 177 Specifying source libraries (SYSLIB) . . . . . 220
Example: sorting with input and output Defining the output data set (SYSPRINT) . . . 221
procedures . . . . . . . . . . . . . 178 Directing compiler messages to your terminal
Choosing alternate collating sequences . . . . 179 (SYSTERM) . . . . . . . . . . . . . 221
Sorting on windowed date fields . . . . . . 179 Creating object code (SYSLIN or SYSPUNCH) 221
Preserving the original sequence of records with Creating an associated data file (SYSADATA) 222
equal keys . . . . . . . . . . . . . 180 Defining the output IDL data set (SYSIDL) . . 222
Determining whether the sort or merge was Defining the debug data set (SYSDEBUG) . . . 222
successful . . . . . . . . . . . . . . 180 Specifying compiler options under OS/390 . . . 223
Stopping a sort or merge operation prematurely 181 Specifying compiler options with the PROCESS
Improving sort performance with FASTSRT . . . 181 (CBL) statement . . . . . . . . . . . 223
FASTSRT requirements for JCL (OS/390 only) 181 Example: specifying compiler options using JCL 224
FASTSRT requirements for sort input and Example: specifying compiler options under
output files . . . . . . . . . . . . . 181 TSO . . . . . . . . . . . . . . . 224
Checking for sort errors with NOFASTSRT . . . 183 Compiler options and compiler output under
Controlling sort behavior . . . . . . . . . 184 OS/390 . . . . . . . . . . . . . . 224
Compiling multiple programs (batch compilation) 226
Contents v
Example: batch compilation . . . . . . . 226 External data . . . . . . . . . . . . 267
Specifying compiler options in a batch QSAM input/output buffers . . . . . . . 267
compilation . . . . . . . . . . . . . 227 DATEPROC . . . . . . . . . . . . . . 267
Example: precedence of options in a batch DBCS . . . . . . . . . . . . . . . . 269
compilation . . . . . . . . . . . . . 228 DECK . . . . . . . . . . . . . . . . 269
Example: LANGUAGE option in a batch DIAGTRUNC . . . . . . . . . . . . . 269
compilation . . . . . . . . . . . . . 229 DISK/PRINT . . . . . . . . . . . . . 270
Correcting errors in your source program . . . . 230 DLL . . . . . . . . . . . . . . . . 270
Generating a list of compiler error messages . . 230 DUMP . . . . . . . . . . . . . . . 271
Messages and listings for compiler-detected DYNAM . . . . . . . . . . . . . . . 272
errors . . . . . . . . . . . . . . . 231 EXIT . . . . . . . . . . . . . . . . 272
Format of compiler error messages . . . . . 231 EXPORTALL . . . . . . . . . . . . . 272
Severity codes for compiler error messages . . 232 FASTSRT . . . . . . . . . . . . . . . 273
FLAG . . . . . . . . . . . . . . . . 274
Chapter 14. Compiling under OS/390 FLAGMIG . . . . . . . . . . . . . . 275
UNIX . . . . . . . . . . . . . . . 235 FLAGSTD . . . . . . . . . . . . . . 275
IDLGEN . . . . . . . . . . . . . . . 277
Setting environment variables under OS/390 UNIX 235
INTDATE . . . . . . . . . . . . . . 278
Specifying compiler options under OS/390 UNIX 236
LANGUAGE . . . . . . . . . . . . . 279
Compiling and linking with the cob2 command 237
LIB . . . . . . . . . . . . . . . . . 280
Defining input and output . . . . . . . . 237
LINECOUNT . . . . . . . . . . . . . 280
Creating a DLL . . . . . . . . . . . . 238
LIST . . . . . . . . . . . . . . . . 281
Example: using cob2 to compile under OS/390
MAP . . . . . . . . . . . . . . . . 281
UNIX . . . . . . . . . . . . . . . 238
NAME . . . . . . . . . . . . . . . 282
cob2 . . . . . . . . . . . . . . . 239
NUMBER . . . . . . . . . . . . . . 283
cob2 input and output files . . . . . . . . 240
NUMPROC . . . . . . . . . . . . . . 283
Compiling using scripts . . . . . . . . . . 241
OBJECT . . . . . . . . . . . . . . . 284
OFFSET . . . . . . . . . . . . . . . 285
Chapter 15. Compiling under CMS 243 OPTIMIZE . . . . . . . . . . . . . . 285
Accessing the compiler (CP LINK and ACCESS) 243 Unused data items: . . . . . . . . . . 286
Specifying a source program to compile . . . . 244 OUTDD . . . . . . . . . . . . . . . 286
COBOL2 . . . . . . . . . . . . . . 244 PGMNAME . . . . . . . . . . . . . . 287
Using compiler-directing statements . . . . . . 245 PGMNAME(COMPAT) . . . . . . . . . 287
Specifying compiler options under CMS . . . . 246 PGMNAME(LONGUPPER). . . . . . . . 288
Using parentheses in COBOL2 . . . . . . 246 PGMNAME(LONGMIXED) . . . . . . . 288
Abbreviating compiler options . . . . . . 246 PGMNAME usage notes. . . . . . . . . 288
Using logical line-editing characters . . . . . 247 QUOTE/APOST . . . . . . . . . . . . 289
Additional compiler options under CMS . . . 247 RENT . . . . . . . . . . . . . . . . 289
Differences in compiler options under CMS . . 248 RMODE . . . . . . . . . . . . . . . 290
Precedence of compiler options under CMS . . 248 SEQUENCE . . . . . . . . . . . . . . 291
Files used by the compiler under CMS . . . . 248 SIZE . . . . . . . . . . . . . . . . 291
Naming generated files under CMS . . . . . . 251 SOURCE . . . . . . . . . . . . . . . 292
Overriding FILEDEF . . . . . . . . . . 251 SPACE . . . . . . . . . . . . . . . 293
Using system-generated names . . . . . . 251 SQL . . . . . . . . . . . . . . . . 293
Correcting errors . . . . . . . . . . . . 252 SSRANGE . . . . . . . . . . . . . . 294
Error messages from COBOL2 . . . . . . . 252 TERMINAL . . . . . . . . . . . . . . 295
TEST . . . . . . . . . . . . . . . . 295
Chapter 16. Compiler options . . . . 257 TRUNC . . . . . . . . . . . . . . . 297
Option settings for COBOL 85 Standard TRUNC example 1 . . . . . . . . . . 298
conformance. . . . . . . . . . . . . . 259 TRUNC example 2 . . . . . . . . . . 299
Conflicting compiler options . . . . . . . . 259 TYPECHK . . . . . . . . . . . . . . 300
ADATA . . . . . . . . . . . . . . . 261 VBREF . . . . . . . . . . . . . . . 301
ANALYZE . . . . . . . . . . . . . . 261 WORD . . . . . . . . . . . . . . . 301
ADV . . . . . . . . . . . . . . . . 262 XREF . . . . . . . . . . . . . . . . 302
ARITH . . . . . . . . . . . . . . . 262 YEARWINDOW . . . . . . . . . . . . 303
AWO . . . . . . . . . . . . . . . . 263 ZWB . . . . . . . . . . . . . . . . 304
BUFSIZE . . . . . . . . . . . . . . . 263 Compiler-directing statements . . . . . . . . 304
CMPR2 . . . . . . . . . . . . . . . 264
COMPILE . . . . . . . . . . . . . . 265 Chapter 17. Debugging . . . . . . . 309
CURRENCY . . . . . . . . . . . . . . 265 Debugging with source language . . . . . . . 310
DATA . . . . . . . . . . . . . . . . 266 Tracing program logic . . . . . . . . . 310
vi Programming Guide
Finding and handling input-output errors . . . 311 DB2 coprocessor . . . . . . . . . . . 358
Validating data . . . . . . . . . . . . 311
Finding uninitialized data . . . . . . . . 311 Chapter 20. Running COBOL
Generating information about procedures . . . 312 programs under IMS . . . . . . . . 359
Debugging using compiler options . . . . . . 313
Compiling and linking COBOL programs for
Finding coding errors . . . . . . . . . 314
running under IMS . . . . . . . . . . . 359
Finding line sequence problems . . . . . . 315
Checking for valid ranges . . . . . . . . 315
Selecting the level of error to be diagnosed . . 316 Chapter 21. Running COBOL
Finding program entity definitions and programs under OS/390 UNIX . . . . 361
references . . . . . . . . . . . . . 317 Running in OS/390 UNIX environments . . . . 361
Listing data items . . . . . . . . . . . 318 Setting and accessing environment variables . . . 362
Getting listings . . . . . . . . . . . . . 319 Setting environment variables that affect
Example: short listing . . . . . . . . . 320 execution . . . . . . . . . . . . . . 362
Example: SOURCE and NUMBER output . . . 323 Resetting environment variables . . . . . . 363
Example: embedded map summary . . . . . 325 Accessing environment variables . . . . . . 363
Terms used in MAP output. . . . . . . . 326 Example: accessing environment variables . . . 363
Symbols used in LIST and MAP output . . . 326 Calling UNIX/POSIX APIs . . . . . . . . . 364
Example: nested program map . . . . . . 328 fork, exec, and spawn . . . . . . . . . 364
Reading LIST output . . . . . . . . . . 328 Samples . . . . . . . . . . . . . . 365
Example: XREF output - data-name Accessing main program parameters . . . . . 365
cross-references. . . . . . . . . . . . 340 Example: accessing main program parameters 366
Example: XREF output - program-name
cross-references. . . . . . . . . . . . 341 Chapter 22. Running COBOL
Example: embedded cross-reference . . . . . 341 programs under CMS . . . . . . . . 369
Example: OFFSET compiler output . . . . . 342 Run-time restrictions under CMS . . . . . . . 369
Example: VBREF compiler output . . . . . 343 Handling QSAM files under CMS . . . . . . 369
Preparing to use the debugger. . . . . . . . 343 Run-time message IGZ0002S . . . . . . . . 370
Contents vii
Creating and freeing instances of classes . . . 390 Coordinating procedural code with interface
Manipulating object references . . . . . . 391 actions . . . . . . . . . . . . . . 452
Invoking methods . . . . . . . . . . . 391 Integrating procedural code into OO systems 452
Example: defining a client . . . . . . . . 392 Changing procedural code . . . . . . . . 453
Defining a subclass . . . . . . . . . . . 393 Converting from procedure-oriented to OO
CLASS-ID paragraph for defining a subclass 394 programs . . . . . . . . . . . . . . . 453
REPOSITORY paragraph for defining a subclass 394 Identifying objects . . . . . . . . . . . 454
WORKING-STORAGE SECTION for defining a Analyzing data flow and usage . . . . . . 454
subclass . . . . . . . . . . . . . . 395 Reallocating code to objects . . . . . . . 454
Defining a subclass method . . . . . . . 395 Writing the object-oriented code . . . . . . 455
Example: defining a subclass (with methods) 396
Defining a metaclass . . . . . . . . . . . 405
Part 5. Working with more
CLASS-ID paragraph for defining a metaclass 406
REPOSITORY paragraph for defining a complex applications . . . . . . . 457
metaclass . . . . . . . . . . . . . . 406
WORKING-STORAGE SECTION for defining a Chapter 28. Using subprograms . . . 459
metaclass . . . . . . . . . . . . . . 406 Main programs, subprograms, and calls . . . . 459
Defining a metaclass method . . . . . . . 406 Ending and reentering main programs or
Changing the definition of a class or subclass 407 subprograms . . . . . . . . . . . . . 460
Changing a client program . . . . . . . . 407 Transferring control to another program . . . . 461
Example: defining a metaclass (with methods) 408 Making static calls. . . . . . . . . . . 462
Making dynamic calls . . . . . . . . . 462
Chapter 25. System Object Model. . . 415 Performance considerations of static and
SOM Interface Repository . . . . . . . . . 415 dynamic calls . . . . . . . . . . . . 464
Accessing the SOM Interface Repository . . . 415 Making both static and dynamic calls . . . . 465
Populating the SOM Interface Repository . . . 416 Example: static and dynamic CALL statements 465
SOM environment variables . . . . . . . . 417 NODYNAM restriction (CMS only) . . . . . 467
Example: sample JCL for an object-oriented Calling nested COBOL programs . . . . . . 468
application . . . . . . . . . . . . . 418 Making recursive calls . . . . . . . . . . 472
SOM services . . . . . . . . . . . . . 420 Calling to and from object-oriented programs . . 472
SOM methods and functions . . . . . . . 420 Using procedure pointers . . . . . . . . . 472
Class initialization . . . . . . . . . . . 421 Calling a C function-pointer . . . . . . . 473
Changing SOM class interfaces . . . . . . 422 Calling to alternate entry points . . . . . . 473
Making programs reentrant . . . . . . . . 474
Chapter 26. Using SOM IDL-based
class libraries . . . . . . . . . . . 425 Chapter 29. Sharing data . . . . . . 475
SOM objects . . . . . . . . . . . . . . 425 Passing data . . . . . . . . . . . . . . 475
SOM IDL . . . . . . . . . . . . . . . 426 Describing arguments in the calling program 477
Mapping IDL to COBOL . . . . . . . . . 427 Describing parameters in the called program 477
Using IDL operations. . . . . . . . . . 427 Coding the LINKAGE SECTION . . . . . . . 477
Expressing IDL attributes . . . . . . . . 428 Coding the PROCEDURE DIVISION for passing
Common IDL types . . . . . . . . . . 429 arguments . . . . . . . . . . . . . . 478
Complex IDL types . . . . . . . . . . 432 Grouping data to be passed . . . . . . . 478
Passing COBOL arguments and return values 435 Handling null-terminated strings . . . . . . 478
Example: using a SOM IDL-based class library 440 Using pointers to process a chained list . . . 479
Handling errors and exceptions . . . . . . . 442 Passing return code information . . . . . . . 482
Passing environment variables. . . . . . . 443 Understanding the RETURN-CODE special
Checking the exception type field . . . . . 443 register . . . . . . . . . . . . . . 482
Handling exceptions . . . . . . . . . . 443 Using PROCEDURE DIVISION RETURNING . .
Example: checking SOM exceptions . . . . . 443 .. . . . . . . . . . . . . . . . . 482
Creating and initializing object instances . . . . 445 Specifying CALL . . . RETURNING . . . . . . 483
Looking at the IDL file . . . . . . . . . . 446 Sharing data by using the EXTERNAL clause. . . 483
Avoiding memory leaks . . . . . . . . . . 447 Sharing files between programs (external files) . . 483
Example: COBOL variable-length string class 448 Example: using external files . . . . . . . 484
Source code for helper routines . . . . . . . 450
Chapter 30. Creating a DLL or a DLL
Chapter 27. Wrapping or converting application . . . . . . . . . . . . 489
procedure-oriented programs . . . . 451 Dynamic link libraries (DLLs) . . . . . . . . 489
OO view of COBOL programs. . . . . . . . 451 Compiling programs to create DLLs . . . . . . 490
Wrapping procedure-oriented programs . . . . 452 Linking DLLs . . . . . . . . . . . . . 491
Contents ix
Intrinsic functions evaluated in fixed-point Processing of PRTEXIT . . . . . . . . . . 580
arithmetic . . . . . . . . . . . . . . 565 Parameter list for PRTEXIT . . . . . . . . 581
Integer functions . . . . . . . . . . . 565 Processing of ADEXIT . . . . . . . . . . 582
Mixed functions . . . . . . . . . . . 565 Parameter list for ADEXIT . . . . . . . . 582
Floating-point data and intermediate results . . . 566 Error handling for exit modules . . . . . . . 583
Exponentiations evaluated in floating-point Example: SYSIN user exit . . . . . . . . . 583
arithmetic . . . . . . . . . . . . . 567
Intrinsic functions evaluated in floating-point Appendix D. Sample programs . . . . 587
arithmetic . . . . . . . . . . . . . 567 IGYTCARA: batch application . . . . . . . . 587
ON SIZE ERROR and intermediate results. . . . 567 Input data for IGYTCARA . . . . . . . . 588
Arithmetic expressions in nonarithmetic statements 568 Report produced by IGYTCARA . . . . . . 589
Running IGYTCARA . . . . . . . . . . 590
Appendix B. Complex OCCURS IGYTCARB: interactive program . . . . . . . 592
DEPENDING ON . . . . . . . . . . 569 Running IGYTCARB . . . . . . . . . . 592
Example: complex ODO . . . . . . . . . . 569 IGYTSALE: nested program application . . . . 595
How length is calculated . . . . . . . . 570 Input data for IGYTSALE . . . . . . . . 597
Setting values of ODO objects . . . . . . . 570 Reports produced by IGYTSALE . . . . . . 598
Effects of change in ODO object value . . . . . 570 Running IGYTSALE . . . . . . . . . . 602
Preventing index errors when changing ODO Language elements and concepts that are
object value . . . . . . . . . . . . . 571 illustrated . . . . . . . . . . . . . . 604
Preventing overlay when adding elements to a
variable table . . . . . . . . . . . . 571 Notices . . . . . . . . . . . . . . 609
Trademarks . . . . . . . . . . . . . . 610
Appendix C. EXIT compiler option . . 575
Using the user-exit work area . . . . . . . . 576 Glossary . . . . . . . . . . . . . 611
Calling from exit modules . . . . . . . . . 576
Processing of INEXIT. . . . . . . . . . . 577 List of resources . . . . . . . . . . 633
Parameter list for INEXIT . . . . . . . . 577 COBOL for OS/390 & VM . . . . . . . . . 633
Processing of LIBEXIT . . . . . . . . . . 578 Related publications . . . . . . . . . . . 633
Processing of LIBEXIT with nested COPY
statements . . . . . . . . . . . . . 578
Parameter list for LIBEXIT . . . . . . . . 579
Index . . . . . . . . . . . . . . . 635
x Programming Guide
About this book
Welcome to IBM COBOL for OS/390 & VM, IBM’s latest host COBOL compiler!
This version of IBM COBOL for OS/390 & VM is fully source and object
compatible with COBOL for MVS & VM Version 1, with the exception of programs
containing object-oriented language constructs, which must be recompiled to
enable support for OS/390 SOMobjects.
IBM COBOL for OS/390 & VM is referred to as “COBOL for OS/390 & VM”
throughout this publication.
IBM Language Environment for OS/390 & VM provides the run-time environment
and run-time services required to run your COBOL for OS/390 & VM programs.
You will find information on link-editing and running programs in the IBM
Language Environment Programming Guide and IBM Language Environment
Programming Reference.
For a comparison of commonly used COBOL for OS/390 & VM and IBM
Language Environment for OS/390 & VM terms, see “Comparison of
commonly-used terms” on page xiii.
Abbreviated terms
Certain terms are used in a shortened form in this book. Abbreviations for the
product names used most frequently in this book are listed alphabetically in the
following table. Abbreviations for other terms, if not commonly understood, are
shown in italics the first time they appear, and are listed in the glossary in the back
of this book.
If an optional item appears above the main path, that item has no effect on the
execution of the statement and is used only for readability.
If you can choose from two or more items, they appear vertically, in a stack.
If you must choose one of the items, one item of the stack appears on the main
path.
If one of the items is the default, it appears above the main path and the
remaining choices are shown below.
An arrow returning to the left, above the main line, indicates an item that can be
repeated.
If the repeat arrow contains a comma, you must separate repeated items with a
comma.
A repeat arrow above a stack indicates that you can repeat the items in the
stack.
v Keywords appear in uppercase (for example, FROM). They must be spelled exactly
as shown. Variables appear in all lowercase letters (for example, column-name).
They represent user-supplied names or values.
v If punctuation marks, parentheses, arithmetic operators, or other such symbols
are shown, you must enter them as part of the syntax.
Where it helps to more clearly separate the examples from the explanatory text,
they are presented in a different font style.
COBOL keywords and compiler options appearing in text are generally shown in
SMALL UPPER CASE. Other terms such as program variable names or method names
are sometimes shown in a different font style for clarity.
Summary of changes
This section lists the key changes that have been made to IBM COBOL for OS/390
& VM. Those documented in this publication have an associated page reference for
your convenience.
The latest technical changes are marked by a change bar in the left margin. Many
corrections have been made without comment.
Major changes
v Enhanced support for decimal data, raising the maximum number of decimal
digits from 18 to 31 and providing an extended-precision mode for arithmetic
calculations (“ARITH” on page 262)
v Enhanced production debugging using overlay hooks rather than compiled-in
hooks, with symbolic debugging information optionally in a separate file
(“TEST” on page 295)
v Support for compiling, linking, and executing in the OS/390 UNIX System
Services environment, with COBOL files able to reside in the HFS (hierarchical
file system) (“Chapter 14. Compiling under OS/390 UNIX” on page 235)
v Toleration of fork(), exec(), and spawn(); and the ability to call UNIX/POSIX
functions (“Calling UNIX/POSIX APIs” on page 364)
v Enhanced input-output function, permitting dynamic file allocation by means of
an environment variable named in SELECT . . . ASSIGN, and the accessing of
sequentially organized HFS files including by means of ACCEPT and DISPLAY
(“Allocating files” on page 105)
v Support for line-sequential file organization for accessing HFS files that contain
text data, with records delimited by the new-line character (“Chapter 10.
Processing line-sequential files” on page 163)
v COMP-5 data type, new to host COBOL, allowing values of magnitude up to the
capacity of the native binary representation (“Formats for numeric data” on
page 36)
v Significant performance improvement in processing binary data with the
TRUNC(BIN) compiler option (“TRUNC” on page 297)
For further details, see the OS/390 SOMobjects Programmer’s Guide, and
“Chapter 25. System Object Model” on page 415.
v The INTDATE compiler option is no longer an installation option only—it can now
be specified as an option when invoking the compiler. See “INTDATE” on
page 278.
2 Programming Guide
Parameters for creating QSAM files . . . . 123 Closing VSAM files . . . . . . . . . . 150
Retrieving QSAM files . . . . . . . . . 123 Handling errors in VSAM files . . . . . . . 151
Parameters for retrieving QSAM files . . . 124 Protecting VSAM files with a password . . . . 151
Ensuring file attributes match your program 124 Example: password protection for a VSAM
Processing existing files . . . . . . . . 125 indexed file . . . . . . . . . . . . . 152
Defining variable-length (format-V) records 125 Working with VSAM data sets under OS/390 and
Defining format-U records . . . . . . . 125 OS/390 UNIX . . . . . . . . . . . . . 152
Defining fixed-length records . . . . . . 125 Defining VSAM files under OS/390 . . . . . 153
Processing new files . . . . . . . . . 125 Creating alternate indexes . . . . . . . . 154
Processing files dynamically created by Example: entries for alternate indexes . . . 155
COBOL . . . . . . . . . . . . . 126 Allocating VSAM files . . . . . . . . . 156
Using striped extended-format QSAM data sets 126 Sharing VSAM files through RLS . . . . . . 157
Allocation of buffers for QSAM files. . . . 127 Preventing update problems with VSAM files
Accessing HFS files using QSAM . . . . . . . 127 in RLS mode . . . . . . . . . . . 157
Restrictions and usage . . . . . . . . . 127 Restrictions when using RLS . . . . . . 158
Identifying QSAM files to CMS . . . . . . . 128 Handling errors in VSAM files in RLS mode 158
Using FILEDEF. . . . . . . . . . . . 128 Defining VSAM data sets under CMS . . . . . 158
Using LABELDEF . . . . . . . . . . . 129 Improving VSAM performance . . . . . . . 159
Labels for QSAM files . . . . . . . . . . 129
Using trailer and header labels . . . . . . 130 Chapter 10. Processing line-sequential files . . 163
Getting a user-label track . . . . . . . 130 Defining line-sequential files and records in
Handling user labels . . . . . . . . . 130 COBOL . . . . . . . . . . . . . . . 163
Format of standard labels . . . . . . . . 131 Allowable control characters . . . . . . . 164
Standard user labels . . . . . . . . . 131 Describing the structure of a line-sequential file 164
Processing QSAM ASCII files on tape . . . . . 132 Defining and allocating line-sequential files . . . 165
Requesting the ASCII alphabet . . . . . . 132 Coding input-output statements for line-sequential
Defining the record formats . . . . . . . 132 files . . . . . . . . . . . . . . . . 165
Defining the ddname . . . . . . . . . . 132 Opening line-sequential files . . . . . . . 166
Processing ASCII file labels . . . . . . . . . 133 Reading records from line-sequential files . . . 166
Adding records to line-sequential files . . . . 167
Chapter 9. Processing VSAM files. . . . . . 135 Closing line-sequential files. . . . . . . . 167
VSAM files . . . . . . . . . . . . . . 136 Handling errors in line-sequential files . . . . . 168
Defining VSAM file organization and records . . 137
Specifying sequential organization for VSAM Chapter 11. Sorting and merging files . . . . 169
files . . . . . . . . . . . . . . . 138 Sort and merge process . . . . . . . . . . 170
Specifying indexed organization for VSAM files 138 Describing the sort or merge file . . . . . . . 170
Alternate keys . . . . . . . . . . . 139 Describing the input to sorting or merging . . . 171
Alternate index . . . . . . . . . . . 139 Example: describing sort and input files for
Specifying relative organization for VSAM files 139 SORT . . . . . . . . . . . . . . . 171
Fixed-length and variable-length RRDS . . . 140 Coding the input procedure . . . . . . . . 172
Simulating variable-length RRDS . . . . . 140 Describing the output from sorting or merging . . 173
Specifying access modes for VSAM files . . . 141 Coding the output procedure . . . . . . . . 173
Example: using dynamic access with VSAM Coding considerations when using DFSORT on
files . . . . . . . . . . . . . . 141 OS/390 . . . . . . . . . . . . . . 174
Defining record lengths for VSAM files. . . . 141 Example: coding the output procedure when
Defining fixed-length records . . . . . . 142 using DFSORT . . . . . . . . . . . . 174
Defining variable-length records . . . . . 142 Restrictions on input and output procedures . . . 175
Coding input and output statements for VSAM Defining sort and merge data sets under OS/390 175
files . . . . . . . . . . . . . . . . 143 Defining sort and merge files under CMS . . . . 176
File position indicator . . . . . . . . . 144 Sorting variable-length records . . . . . . . 176
Opening a file (ESDS, KSDS, or RRDS) . . . . 145 Requesting the sort or merge . . . . . . . . 177
Opening an empty file . . . . . . . . 145 Setting sort or merge criteria . . . . . . . 177
Statements to load records into a VSAM file 147 Example: sorting with input and output
Opening a loaded file (a file with records) 147 procedures . . . . . . . . . . . . . 178
Reading records from a VSAM file . . . . . 147 Choosing alternate collating sequences . . . . 179
Updating records in a VSAM file . . . . . . 148 Sorting on windowed date fields . . . . . . 179
Adding records to a VSAM file . . . . . . 149 Preserving the original sequence of records with
Adding records sequentially . . . . . . 149 equal keys . . . . . . . . . . . . . 180
Adding records randomly or dynamically 149 Determining whether the sort or merge was
Replacing records in a VSAM file. . . . . . 149 successful . . . . . . . . . . . . . . 180
Deleting records from a VSAM file . . . . . 150 Stopping a sort or merge operation prematurely 181
4 Programming Guide
Chapter 1. Structuring your program
A COBOL program consists of four divisions, each with a specific logical function:
v IDENTIFICATION DIVISION
v ENVIRONMENT DIVISION
v DATA DIVISION
v PROCEDURE DIVISION
Only the IDENTIFICATION DIVISION is required.
To define a COBOL class or method, you need to define some divisions differently
than you would for a program.
RELATED TASKS
“Identifying a program”
“Describing the computing environment” on page 7
“Describing the data” on page 12
“Processing the data” on page 17
“Defining a class” on page 378
“Defining a class method” on page 381
Identifying a program
Use the IDENTIFICATION DIVISION to name your program and, if you want, give
other identifying information.
You can use the optional AUTHOR, INSTALLATION, DATE-WRITTEN, and DATE-COMPILED
paragraphs for descriptive information about your program. The data you enter on
the DATE-COMPILED paragraph is replaced with the latest compilation date.
IDENTIFICATION DIVISION.
Program-ID. Helloprog.
Author. A. Programmer.
Installation. Computing Laboratories.
Date-Written. 08/18/1997.
Date-Compiled. 03/30/2000.
Use the PROGRAM-ID paragraph to name your program. The program name that you
assign is used in these ways:
v Other programs use the name to call your program.
v The name appears in the header on each page, except the first page, of the
program listing generated when the program is compiled.
v If you use the NAME compiler option, the name is placed on the NAME linkage
editor control statement to identify the object module created by the
compilation.
Tip: Do not use program names that start with prefixes used by IBM products. If
you try to use programs whose names start with any of the following, your CALL
statements might resolve to IBM library or compiler routines rather than to your
intended program:
RELATED TASKS
“Changing the header of a source listing”
“Identifying a program as recursive”
“Marking a program as callable by containing programs”
“Setting a program to an initial state”
RELATED REFERENCES
Compiler limits (IBM COBOL Language Reference)
Conventions for program names (IBM COBOL Language Reference)
You can code RECURSIVE only on the outermost program of a compilation unit.
Neither nested subprograms nor programs containing nested subprograms can be
recursive.
RELATED TASKS
“Making recursive calls” on page 472
RELATED CONCEPTS
“Nested programs” on page 469
PP 5648-A25 IBM COBOL for OS/390 & VM 2.2.0 Date 03/30/2000 Time 15:05:19 Page 1
6 Programming Guide
You can customize the header on succeeding pages of the listing with the
compiler-directing TITLE statement.
RELATED REFERENCES
TITLE statement (IBM COBOL Language Reference)
RELATED TASKS
“Specifying the collating sequence” on page 8
“Defining symbolic characters” on page 9
“Defining a user-defined class” on page 9
“Defining files to the operating system” on page 10
RELATED REFERENCES
Sections and paragraphs (IBM COBOL Language Reference)
1. The SELECT clause chooses a file in the COBOL program to be associated with an external data set.
| 2. The ASSIGN clause associates the program’s name for the file with the external name for the actual data file. You
| can define the external name with a DD statement or an environment variable.
3. The ORGANIZATION clause describes the file’s organization. For QSAM files, the ORGANIZATION clause is optional.
4. The ACCESS MODE clause defines the manner in which the records are made available for processing—sequential,
| random, or dynamic. For QSAM and line-sequential files, the ACCESS MODE clause is optional. These files always
have sequential organization.
5. For VSAM files, you might have additional statements in the FILE-CONTROL paragraph depending on the type of
VSAM file you use.
RELATED TASKS
“Chapter 8. Processing QSAM files” on page 107
“Chapter 9. Processing VSAM files” on page 135
“Chapter 10. Processing line-sequential files” on page 163
“Describing the computing environment” on page 7
The sequence that you use can be based on one of these alphabets:
v EBCDIC (use NATIVE if the native character set is EBCDIC), the default if you
omit the ALPHABET clause
v ASCII (use STANDARD-1)
v ISO 7-bit code, International Reference Version (use STANDARD-2)
v An alteration of the EBCDIC sequence that you define in the SPECIAL-NAMES
paragraph
RELATED TASKS
“Choosing alternate collating sequences” on page 179
8 Programming Guide
in the SPECIAL-NAMES paragraph, the overall collating sequence is affected, not just
the collating sequence of the characters included in the SPECIAL-NAMES paragraph.
IDENTIFICATION DIVISION.
. . .
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
Source-Computer. IBM-390.
Object-Computer. IBM-390.
RELATED TASKS
“Specifying the collating sequence” on page 8
The class name can be referenced only in a class condition. This user-defined class
is not the same as an object-oriented class.
10 Programming Guide
RELATED TASKS
“Optimizing buffer and device space” on page 12
Rules for using different files: The name you use in the assignment-name of the
| ASSIGN clause must be the same as the ddname in the DD statement, the environment
| variable in the export command, or the ddname in the FILEDEF command. You can
| change the actual file by using the DSNAME in the DD statement, the DSNAME or path
| name in the environment variable, or the fn, ft, and fm in the FILEDEF.
The file-name that you use with the SELECT clause (such as SELECT MASTER) must be
the same as in the FD file-name entry.
| Two files should not use the same ddname or environment variable name in their
SELECT clauses; otherwise, results could be unpredictable. For example, if DISPLAY
| is directed to SYSOUT, do not use SYSOUT as the ddname or environment variable
| name on the SELECT clause for a file.
Example: using different input files on OS/390: Consider a COBOL program that
is used in exactly the same way for several different master files. It contains this
SELECT clause:
SELECT MASTER
ASSIGN TO DA-3330-S-MASTERA
Under OS/390, assume the three possible input files are MASTER1, MASTER2, and
MASTER3. Then you must code one of the following DD statements in the job step
| that calls for program execution, or issue one of the following export commands
| from the same shell from which you run the program, prior to running the
| program:
//MASTERA DD DSNAME=MY.MASTER1, . . .
export MASTERA=DSN(MY.MASTER1),...
//MASTERA DD DSNAME=MY.MASTER2, . . .
export MASTERA=DSN(MY.MASTER2),...
//MASTERA DD DSNAME=MY.MASTER3, . . .
export MASTERA=DSN(MY.MASTER3),...
Any reference in the program to MASTERA will therefore be a reference to the file
| currently assigned to ddname or environment variable name MASTERA.
| Notice that in this example, you cannot use the PATH(path) form of the export
| command to reference a line-sequential file in the HFS, because you cannot specify
| an organization field (S- or AS-) with a line-sequential file.
Under VM, assume the three possible input files on your A-disk are MASTER1
INPUT, MASTER2 INPUT, and MASTER3 INPUT. Then you need to issue one of the
following FILEDEF commands before running the program:
FILEDEF MASTERA DISK MASTER1 INPUT A1 . . .
Any reference in the program to MASTERA will therefore be a reference to the file
named in the FILEDEF command.
The APPLY WRITE-ONLY clause has meaning only for sequential files that have
variable-length records and are blocked.
The AWO compiler option applies an implicit APPLY WRITE-ONLY clause to all eligible
files. The NOAWO compiler option has no effect on files that have the APPLY
WRITE-ONLY clause specified. The APPLY WRITE-ONLY clause takes precedence over
the NOAWO compiler option.
The APPLY-WRITE ONLY clause can cause input files to use a record area rather than
process the data in the buffer. This use might affect the processing of both input
files and output files.
RELATED REFERENCES
“AWO” on page 263
The IBM COBOL for OS/390 & VM compiler limits the maximum size of DATA
DIVISION elements.
12 Programming Guide
RELATED CONCEPTS
“Comparison of WORKING-STORAGE and LOCAL-STORAGE” on page 15
RELATED TASKS
“Using data in input and output operations”
“Using data from another program” on page 16
RELATED REFERENCES
Compiler limits (IBM COBOL Language Reference)
Programs in the same run unit can share, or have access to, common files. The
method for doing this depends on whether the programs are part of a nested
(contained) structure or are separately compiled (including programs compiled as
part of a batch sequence).
You can use the EXTERNAL clause for separately compiled programs. A file that is
defined as EXTERNAL can be referenced by any program in the run unit that
describes the file.
RELATED CONCEPTS
“Nested programs” on page 469
RELATED TASKS
“Sharing files between programs (external files)” on page 483
RELATED REFERENCES
“FILE SECTION entries”
14 Programming Guide
Clause To define Notes
CODE-SET ASCII or EBCDIC files QSAM only.
RELATED CONCEPTS
“Labels for QSAM files” on page 129
RELATED CONCEPTS
“Example: storage sections”
RELATED TASKS
“Ending and reentering main programs or subprograms” on page 460
RELATED REFERENCES
Working-Storage section (IBM COBOL Language Reference)
Local-Storage section (IBM COBOL Language Reference)
if numb = 0
move 1 to fact
else
subtract 1 from numb
call 'factorial'
multiply num by fact
end-if.
The following tables show the changing values of the data items in LOCAL-STORAGE
(L-S) and WORKING-STORAGE (W-S) in the successive recursive calls of the program,
and in the ensuing gobacks. During the gobacks, fact progressively accumulates
the value of 5! (five factorial).
Recursive
CALLs: Main 1 2 3 4 5
___________________________________
L-S num 5 4 3 2 1 0
___________________________________
W-S numb 5 4 3 2 1 0
fact 0 0 0 0 0 0
___________________________________
Recursive
GOBACKs: 5 4 3 2 1 Main
____________________________________
L-S num 0 1 2 3 4 5
____________________________________
W-S numb 0 0 0 0 0 0
fact 1 1 2 6 24 120
____________________________________
RELATED CONCEPTS
“Comparison of WORKING-STORAGE and LOCAL-STORAGE” on page 15
RELATED TASKS
“Sharing data in separately compiled programs”
“Sharing data in nested programs” on page 17
RELATED TASKS
“Passing data” on page 475
16 Programming Guide
Sharing data in nested programs
Some applications consist of nested programs—programs that are contained in
other programs. Level-01 LINKAGE SECTION data items can include the GLOBAL
attribute. This attribute allows any nested program that includes the declarations
to access these LINKAGE SECTION data items.
A nested program can also access data items in a sibling program (one at the same
nesting level in the same containing program) that is declared with the COMMON
attribute.
RELATED CONCEPTS
“Nested programs” on page 469
The PROCEDURE DIVISION begins with the division header and a procedure-name
header. The division header for a program can simply be:
PROCEDURE DIVISION.
You can code your division header to receive parameters with the USING phrase or
to return a value with the RETURNING phrase.
Be sure to define the dataname in the LINKAGE SECTION of the DATA DIVISION.
To receive a parameter that was passed by value, code the division header for a
program as follows:
PROCEDURE DIVISION USING BY VALUE dataname
You can also combine USING and RETURNING in a PROCEDURE DIVISION header:
PROCEDURE DIVISION USING dataname RETURNING dataname2
Be sure to define dataname and dataname2 in the LINKAGE SECTION of the DATA
DIVISION.
RELATED CONCEPTS
“How logic is divided in the PROCEDURE DIVISION”
RELATED TASKS
“Eliminating repetitive coding” on page 551
RELATED CONCEPTS
“Compiler-directing statements” on page 20
“Scope terminators” on page 20
“Imperative statements”
“Conditional statements” on page 19
“Declaratives” on page 21
RELATED REFERENCES
PROCEDURE DIVISION structure (IBM COBOL Language Reference)
Imperative statements
An imperative statement indicates an unconditional action to be taken (such as
ADD, MOVE, INVOKE, or CLOSE).
RELATED CONCEPTS
“Conditional statements” on page 19
“Scope terminators” on page 20
18 Programming Guide
Conditional statements
A conditional statement is either a simple conditional statement (IF, EVALUATE,
SEARCH) or a conditional statement made up of an imperative statement that
includes a conditional phrase or option.
You can end a conditional statement with an implicit or explicit scope terminator.
If you end a conditional statement explicitly, it becomes a delimited scope
statement (which is an imperative statement).
An explicit scope terminator is required for the inline PERFORM statement, but it is
not valid for the out-of-line PERFORM statement.
For additional program control, you can use the NOT phrase with conditional
statements. For example, you can provide instructions to be performed when a
particular exception does not occur, such as NOT ON SIZE ERROR. The NOT phrase
cannot be used with the ON OVERFLOW phrase of the CALL statement, but it can be
used with the ON EXCEPTION phrase.
The following statements are examples of conditional statements if they are coded
without scope terminators:
v Arithmetic statement with ON SIZE ERROR
v Data-manipulation statements with ON OVERFLOW
v CALL statements with ON OVERFLOW
v I/O statements with INVALID KEY, AT END, or AT END-OF-PAGE
v RETURN with AT END
RELATED CONCEPTS
“Imperative statements” on page 18
“Scope terminators” on page 20
RELATED REFERENCES
Conditional statements (IBM COBOL Language Reference)
Compiler-directing statements
A compiler-directing statement is not part of the program logic. A
compiler-directing statement causes the compiler to take specific action about the
program structure, COPY processing, listing control, or control flow.
RELATED REFERENCES
“Compiler-directing statements” on page 304
Compiler-directing statements (IBM COBOL Language Reference)
Scope terminators
Scope terminators can be explicit or implicit. Explicit scope terminators end a verb
without ending a sentence. They consist of END followed by a hyphen and the
name of the verb being terminated, such as END-IF. An implicit scope terminator is
a period (.) that ends the scope of all previous statements not yet ended.
Each of the two periods in the following program fragment ends an IF statement,
making the code equivalent to the code after it that instead uses explicit scope
terminators:
IF ITEM = “A”
DISPLAY “THE VALUE OF ITEM IS ” ITEM
ADD 1 TO TOTAL
MOVE “C” TO ITEM
DISPLAY “THE VALUE OF ITEM IS NOW ” ITEM.
IF ITEM = “B”
ADD 2 TO TOTAL.
IF ITEM = “A”
DISPLAY “THE VALUE OF ITEM IS ” ITEM
ADD 1 TO TOTAL
MOVE “C” TO ITEM
DISPLAY “THE VALUE OF ITEM IS NOW ” ITEM
END-IF
IF ITEM = “B”
ADD 2 TO TOTAL
END-IF
If you use implicit terminators, the end of statements can be unclear. As a result,
you might end statements unintentionally, changing your program’s logic. Explicit
scope terminators make a program easier to understand and prevent unintentional
ending of statements. For example, in the program fragment below, changing the
location of the first period in the first implicit scope example changes the meaning
of the code:
IF ITEM = “A”
DISPLAY “VALUE OF ITEM IS ” ITEM
ADD 1 TO TOTAL.
MOVE “C” TO ITEM
DISPLAY “ VALUE OF ITEM IS NOW ” ITEM
IF ITEM = “B”
ADD 2 TO TOTAL.
The MOVE statement and the DISPLAY statement after it are performed regardless of
the value of ITEM, despite what the indentation indicates, because the first period
terminates the IF statement.
20 Programming Guide
For improved program clarity and to avoid unintentional ending of statements, use
explicit scope terminators, especially within paragraphs. Use implicit scope
terminators only at the end of a paragraph or the end of a program.
To ensure that the explicit scope terminator is paired with the intended statement,
the preceding example can be recoded in this way:
READ FILE1
AT END
MOVE A TO B
READ FILE2
END-READ
END-READ
RELATED CONCEPTS
“Conditional statements” on page 19
“Imperative statements” on page 18
Declaratives
Declaratives provide one or more special-purpose sections that are executed when
an exception condition occurs.
Start each declarative section with a USE statement that identifies the function of
the section; in the procedures, specify the actions to be taken when the condition
occurs.
RELATED TASKS
“Finding and handling input-output errors” on page 311
RELATED REFERENCES
Declaratives (IBM COBOL Language Reference)
Variables
A variable is a data item whose value can change during a program. The values
are restricted, however, to the data type that you define when you give the
variable a name and a length. For example, if a customer name is a variable in
your program, you could code:
Data Division.
. . .
01 Customer-Name Pic X(20).
01 Original-Customer-Name Pic X(20).
. . .
Procedure Division.
. . .
Move Customer-Name to Original-Customer-Name
. . .
Literals
A literal is a character string whose value is given by the characters themselves.
When you know the value you want to use for a data item, use a literal
representation of the data value in the PROCEDURE DIVISION. You do not need to
define it or refer to a data-name. For example, you can prepare an error message
for an output file this way:
Move “Name is not valid” To Customer-Name
Constants
A constant is a data item that has only one value. COBOL does not define a
construct specifically for constants. However, most COBOL programmers define a
data item with an initial VALUE (as opposed to initializing a variable using the
INITIALIZE statement). For example:
Data Division.
. . .
01 Report-Header pic x(50) value “Company Sales Report”.
. . .
01 Interest pic 9v9999 value 1.0265.
Figurative constants
A variable is a data item whose value can change during a program. Certain
commonly used constants and literals are provided as reserved words called
figurative constants: ZERO, SPACE, HIGH-VALUE, LOW-VALUE, QUOTE, NULL, and ALL.
Because they represent fixed values, figurative constants do not require a data
definition. For example:
Move Spaces To Report-Header
RELATED REFERENCES
PICTURE clause (IBM COBOL Language Reference)
Literals (IBM COBOL Language Reference)
Figurative constants (IBM COBOL Language Reference)
24 Programming Guide
Assigning values to data items
After you have defined a data item, you can assign a value to it at any time.
Assignment takes many forms in COBOL, depending on what you want to do.
RELATED TASKS
“Initializing a structure (INITIALIZE)” on page 26
“Assigning values to variables or structures (MOVE)” on page 27
“Assigning arithmetic results (MOVE or COMPUTE)” on page 27
“Assigning input from a screen or file (ACCEPT)” on page 28
“Displaying values on a screen or in a file (DISPLAY)” on page 29
RELATED TASKS
“Initializing a structure (INITIALIZE)”
26 Programming Guide
The following example shows how you can reset fields in a transaction record
produced by a program to spaces and zeros. The fields are not identical in each
record produced.
01 TRANSACTION-OUT.
05 TRANSACTION-CODE PIC X.
05 PART-NUMBER PIC 9(6).
05 TRANSACTION-QUANTITY PIC 9(5).
05 PRICE-FIELDS.
10 UNIT-PRICE PIC 9(5)V9(2).
10 DISCOUNT PIC V9(2).
10 SALES-PRICE PIC 9(5)V9(2).
. . .
INITIALIZE TRANSACTION-OUT
For example, the following statement assigns the contents of the variable
Customer-Name to the variable Orig-Customer-Name:
Move Customer-Name to Orig-Customer-Name
When you move a group item to another group item, be sure the subordinate data
descriptions are compatible. The compiler performs all MOVE statements regardless
of whether the items fit, even if a destructive overlap could occur at run time,
For variables containing numbers, moves can be more complicated because there
are several ways numbers are represented. In general, the algebraic values of
numbers are moved if possible (as opposed to the digit-by-digit move performed
with character data):
01 Item-x Pic 999v9.
. . .
Move 3.06 to Item-x
This move would result in Item-x containing the value 3.0, represented by 0030.
When significant left-order digits would be lost in execution, the COMPUTE statement
can detect the condition and allow you to handle it.
When you use the ON SIZE ERROR phrase of the COMPUTE statement, the compiler
generates code to detect a size-overflow condition. If the condition occurs, the code
in the ON SIZE ERROR phrase is performed, and the content of z remains
unchanged. If the ON SIZE ERROR phrase is not specified, the assignment is carried
out with truncation. There is no ON SIZE ERROR support for the MOVE statement.
You can also use the COMPUTE statement to assign the result of an arithmetic
expression (or intrinsic function) to a variable. For example:
Compute z = y + (x ** 3)
Compute x = Function Max(x y z)
As a result of this call, the variable Result is assigned to be the absolute value of
the value that is in the variable Arg; the variable Feedback-code contains the return
code indicating whether the service completed successfully. You have to define all
the variables in the Data Division using the correct descriptions, according to the
requirements of the particular callable service you are using. For the example
above, the variables could be defined like this:
77 Arg Pic s9(9) Binary.
77 Feedback-code Pic x(12) Display.
77 Result Pic s9(9) Binary.
RELATED REFERENCES
“DIAGTRUNC” on page 269
Intrinsic functions (IBM COBOL Language Reference)
Callable services (Language Environment Programming Reference)
For example:
Environment Division.
Configuration Section.
Special-Names.
Console is Names-Input.
. . .
Accept Customer-Name From Names-Input
To read from a file instead of the screen, make the following change:
28 Programming Guide
v Change Console to device, where device is any valid system device (for example,
SYSIN). For example:
SYSIN is Names-Inpu
| Note that device can be a ddname that references a hierarchical file system (HFS)
| path. If this DD is not defined and your program is running in an OS/390 UNIX
| environment, stdin is the input source. If this DD is not defined and your
| program is not running in an OS/390 UNIX environment, the ACCEPT statement
| fails.
RELATED REFERENCES
SPECIAL-NAMES paragraph (IBM COBOL Language Reference)
To write data to a destination other than the system logical output device, use the
UPON clause with a destination other than SYSOUT. For example, the following
statement writes to the file specified in the SYSPUNCH DD statement:
Display “Hello” UPON SYSPUNCH.
| Note that you can specify a file in the hierarchical file system (HFS) with this
| ddname. For example, with the following definition, your DISPLAY output is
| written to the HFS file /u/userid/cobol/demo.lst:
| //SYSPUNCH DD PATH='/u/userid/cobol/demo.lst',
| // PATHOPTS=(OWRONLY,OCREAT,OTRUNC),PATHMODE=SIRWXU,
| // FILEDATA=TEXT
The output is directed to the ddname that you specify in the OUTDD compiler
| option. Note that you can specify a file in the hierarchical file system (HFS) with
| this ddname.
| If the OUTDD ddname is not allocated and you are not running in an OS/390 UNIX
| environment, a default DD of SYSOUT=* is allocated.
| If the OUTDD ddname is not allocated and you are running in an OS/390 UNIX
| environment, the _IGZ_SYSOUT environment variable is used as follows:
| Undefined or set to stdout
| Output is routed to stdout (file descriptor 1).
| When DISPLAY output is routed to stdout or stderr, the output is not subdivided
| into records; rather the output is written as a single stream of characters without
| line breaks.
If OUTDD and the Language Environment run-time option MSGFILE both specify the
same ddname, DISPLAY output and Language Environment run-time diagnostics
are both routed to the Language Environment message file.
| If you specify the WITH NO ADVANCING phrase and the output is going to stdout or
| stderr, a new-line character is not appended to the end of the stream. A subsequent
| DISPLAY statement might add additional characters to the end of the stream.
| If you do not specify WITH NO ADVANCING and the output is going to a ddname, the
printer control character ’ ’ (space) is placed into the first output position from the
next DISPLAY statement, indicating single-spaced output.
For example:
DISPLAY “ABC”
DISPLAY “CDEF” WITH NO ADVANCING
DISPLAY “GHIJK” WITH NO ADVANCING
DISPLAY “LMNOPQ”
DISPLAY “RSTUVWX”
If you use the statements above, the result sent to the output device is:
ABC
CDEF
+GHIJK
+LMNOPQ
RSTUVMX
The output printed depends on how the output device interprets printer control
characters.
| If you do not specify the WITH NO ADVANCING phrase and the output is going to
| stdout or stderr, a new-line character is appended to the end of the stream.
RELATED TASKS
“Setting and accessing environment variables” on page 362
“Coding COBOL programs to run under CICS” on page 347
RELATED REFERENCES
DISPLAY statement (IBM COBOL Language Reference)
“OUTDD” on page 286
30 Programming Guide
Using intrinsic functions (built-in functions)
Some high-level programming languages have built-in functions that you can
reference in your program as if they were variables having defined attributes and a
predetermined value. In COBOL, these are called intrinsic functions. They provide
capabilities for manipulating strings and numbers.
A function-identifier represents both the invocation of the function and the data
value returned by the function. Because it actually represents a data item, you can
use a function-identifier in most places in the PROCEDURE DIVISION where a data
item having the attributes of the returned value can be used.
The COBOL word function is a reserved word, but the function names are not
reserved. You can use them in other contexts, such as for the name of a variable.
For example, you could use Sqrt to invoke an intrinsic function and to name a
variable in your program:
Working-Storage Section.
01 x Pic 99 value 2.
01 y Pic 99 value 4.
01 z Pic 99 value 0.
01 Sqrt Pic 99 value 0.
. . .
Compute Sqrt = 16 ** .5
Compute z = x + Function Sqrt(y)
. . .
The functions MAX, MIN, DATEVAL, and UNDATE can return either type of value
depending on the type of arguments you supply.
The functions DATEVAL, UNDATE, and YEARWINDOW are provided with the millennium
language extensions to assist with manipulating and converting windowed date
fields.
In this case, Function Sqrt(5) returns a numeric value. Thus, the three arguments
to the MAX function are all numeric, which is an allowable argument type for this
function.
RELATED TASKS
“Processing table items using intrinsic functions” on page 67
“Converting data items (intrinsic functions)” on page 94
“Evaluating data items (intrinsic functions)” on page 96
Pointers are data items that contain virtual storage addresses. You define them
explicitly with the USAGE IS POINTER clause in the DATA DIVISION or implicitly as
ADDRESS OF special registers.
RELATED TASKS
“Defining a table (OCCURS)” on page 53
32 Programming Guide
Chapter 3. Working with numbers and arithmetic
In general, you can view COBOL numeric data as a series of decimal digit
positions. However, numeric items can also have special properties such as an
arithmetic sign or a currency sign.
This section describes how to define, display, and store numeric data so that you
can perform arithmetic operations efficiently:
v Use the PICTURE clause and the characters 9, +, -, P, S, and V to define numeric
data.
v Use the PICTURE clause and editing characters (such as Z, comma, and period)
along with MOVE and DISPLAY statements to display numeric data.
v Use the USAGE clause with various formats to control how numeric data is stored.
v Use the numeric class test to validate that data values are appropriate.
v Use ADD, SUBTRACT, MULTIPLY, DIVIDE, and COMPUTE statements to perform
arithmetic.
v Use the CURRENCY SIGN clause and appropriate PICTURE characters to designate
the currency you want.
RELATED TASKS
“Defining numeric data”
“Displaying numeric data” on page 34
“Controlling how numeric data is stored” on page 35
“Checking for incompatible data (numeric class test)” on page 42
“Performing arithmetic” on page 43
“Using currency signs” on page 51
| When you compile using the default compiler option ARITH(COMPAT) (referred to as
| compatibility mode), you can code up to 18 digits in the PICTURE clause. When you
| compile using ARITH(EXTEND) (referred to as extended mode), you can code up to 31
| digits in the PICTURE clause.
The field can therefore hold a positive or a negative value. The v indicates the
position of an implied decimal point, but does not contribute to the size of the
However, if you plan to port your program or data to a different machine, you
might want to code the sign as a separate position in storage. In this case, the sign
takes 1 byte:
05 Price Pic s99V99 Sign Is Leading, Separate.
This coding ensures that the convention your machine uses for storing a
nonseparate sign will not cause unexpected results on a machine that uses a
different convention.
Separate signs are also preferable for data items that will be printed or displayed.
You cannot use the PICTURE clause with internal floating-point data (COMP-1 or
COMP-2). However, you can use the VALUE clause to provide an initial value for a
floating-point literal:
05 Compute-result Usage Comp-2 Value 06.23E-24.
RELATED CONCEPTS
“Appendix A. Intermediate results and arithmetic precision” on page 559
RELATED TASKS
“Displaying numeric data”
“Controlling how numeric data is stored” on page 35
“Performing arithmetic” on page 43
RELATED REFERENCES
“Sign representation and processing” on page 41
“ARITH” on page 262
“NUMPROC” on page 283
If the contents of Price are 0150099 (representing the value 1,500.99), then
$ 1,500.99 is displayed when you run the code. The z in the PICTURE clause of
Edited-price indicates the suppression of leading zeros.
34 Programming Guide
You can move numeric-edited items to numeric or numeric-edited items. In the
following example, the value of the numeric-edited item is moved to the numeric
item:
Move Edited-price to Price
Display Price
RELATED TASKS
“Controlling how numeric data is stored”
“Defining numeric data” on page 33
“Performing arithmetic” on page 43
RELATED REFERENCES
MOVE statement (IBM COBOL Language Reference)
COMP and COMP-4 are synonymous with BINARY, and COMP-3 is synonymous with
PACKED-DECIMAL.
Regardless of which USAGE clause you use to control the internal representation of a
value, you use the same PICTURE clause conventions and decimal value in the
VALUE clause (except for floating-point data, for which you cannot use a PICTURE
clause).
RELATED CONCEPTS
“Formats for numeric data”
“Data format conversions” on page 39
“Appendix A. Intermediate results and arithmetic precision” on page 559
RELATED TASKS
“Defining numeric data” on page 33
“Displaying numeric data” on page 34
“Performing arithmetic” on page 43
RELATED REFERENCES
“Conversions and precision” on page 40
“Sign representation and processing” on page 41
External decimal (also known as zoned decimal) items are primarily intended for
receiving and sending numbers between your program and files, terminals, or
printers. You can also use external decimal items as operands and receivers in
arithmetic processing. However, if your program performs a lot of intensive
arithmetic and efficiency is a high priority, COBOL’s computational numeric types
might be a better choice for the data items used in the arithmetic.
The minus signs (-) do not mean that the mantissa and exponent must necessarily
be negative numbers. Instead, they mean that when the number is displayed, the
sign appears as a blank for positive numbers or a minus sign for negative
numbers. If you instead code a plus sign (+), the sign appears as a plus sign for
positive numbers or a minus sign for negative numbers.
36 Programming Guide
As with external decimal numbers, external floating-point numbers have to be
converted (by the compiler) to an internal representation of their numeric value
| before they can be used in arithmetic operations. If you compile with the default
| option ARITH (COMPAT), external floating-point numbers are converted to long
| (64-bit) floating-point format. If you compile with ARITH (EXTEND), they are instead
| converted to extended-precision (128-bit) floating-point format.
You can use binary items, for example, for indexes, subscripts, switches, and
arithmetic operands or results.
Use the TRUNC(STD|OPT|BIN) compiler option to indicate how binary data (BINARY,
COMP, or COMP-4) is to be truncated.
| Data items that you declare as USAGE COMP-5 are represented in storage as binary
| data. However, unlike USAGE COMP items, they can contain values of magnitude up
| to the capacity of the native binary representation (2, 4, or 8 bytes) rather than
| being limited to the value implied by the number of 9s in the PICTURE clause.
| When you move or store numeric data into a COMP-5 item, truncation occurs at the
| binary field size rather than at the COBOL PICTURE size limit. When you reference
| a COMP-5 item, the full binary field size is used in the operation.
| COMP-5 is thus particularly useful for binary data items originating in non-COBOL
| programs where the data might not conform to a COBOL PICTURE clause.
| The table below shows the ranges of values possible for COMP-5 data items.
| Regardless of the setting of the TRUNC compiler option, COMP-5 data items behave
| like binary data does in programs compiled with TRUNC(BIN).
Packed-decimal items occupy 1 byte of storage for every two decimal digits you
code in the PICTURE description, except that the rightmost byte contains only one
digit and the sign. This format is most efficient when you code an odd number of
digits in the PICTURE description, so that the leftmost byte is fully used.
Packed-decimal items are handled as fixed-point numbers for arithmetic purposes.
On OS/390 & VM, COMP-1 and COMP-2 data items are stored in System/390
hexadecimal format.
RELATED CONCEPTS
“Appendix A. Intermediate results and arithmetic precision” on page 559
RELATED REFERENCE
“TRUNC” on page 297
38 Programming Guide
PICTURE and USAGE and
Numeric type optional SIGN clause Value Internal representation
Binary PIC S9999 BINARY + 1234 04 D2
COMP - 1234 FB 2E
COMP-4
| COMP-5 + 123451 30 39
| - 123451 CF C7
PIC 9999 BINARY 1234 04 D2
COMP
COMP-4
| COMP-5 600001 EA 60
Internal PIC S9999 PACKED-DECIMAL + 1234 01 23 4C
decimal COMP-3 - 1234 01 23 4D
PIC 9999 PACKED-DECIMAL + 1234 01 23 4F
COMP-3 - 1234 01 23 4F
Internal COMP-1 + 1234 43 4D 20 00
floating
point
Internal COMP-2 + 1234 43 4D 20 00 00 00 00 00
floating - 1234 C3 4D 20 00 00 00 00 00
point
External PIC +9(2).9(2)E+99 DISPLAY + 1234 4E F1 F2 4B F3
floating F4 C5 4E F0 F2
point
- 1234 60 F1 F2 4B F3
F4 C5 4E F0 F2
| 1. The example demonstrates that COMP-5 data items can contain values of magnitude up to the capacity of the
| native binary representation (2, 4, or 8 bytes), rather than being limited to the value implied by the number of 9s
| in the PICTURE clause.
Conversion generally requires additional storage and processing time because data
is moved to an internal work area and converted before the operation is
performed. The results might also have to be moved back into a work area and
converted again.
RELATED REFERENCES
“Conversions and precision”
“Sign representation and processing” on page 41
When the compiler converts short form to long form for comparisons, zeros are
used for padding the shorter number.
When a USAGE COMP-1 data item is moved to a fixed-point data item with more
than nine digits, the fixed-point data item will receive only nine significant digits,
and the remaining digits will be zero.
When a USAGE COMP-2 data item is moved to a fixed-point data item with more
than 18 digits, the fixed-point data item will receive only 18 significant digits, and
the remaining digits will be zero.
If a USAGE COMP-1 data item is moved to a fixed-point data item of nine or more
digits and then returned to the USAGE COMP-1 data item, the original value is
recovered.
If a fixed-point data item with 15 or fewer digits is moved to a USAGE COMP-2 data
item and then returned to the fixed-point data item, the original value is recovered.
If a USAGE COMP-2 data item is moved to a USAGE COMP-1 data item, rounding occurs
in the low-order position of the target data item.
If a fixed-point data item is moved to an external floating-point data item and the
PICTURE of the fixed-point data item contains more digit positions than the PICTURE
of the external floating-point data item, rounding occurs in the low-order position
of the target data item.
40 Programming Guide
RELATED CONCEPTS
“Appendix A. Intermediate results and arithmetic precision” on page 559
Given X’sd’, where s is the sign representation and d represents the digit, the valid
sign representations for external decimal (USAGE DISPLAY without the SIGN IS
SEPARATE clause) are:
Positive:
C, A, E, and F
Negative:
D and B
The COBOL NUMPROC compiler option affects sign processing for external decimal
and internal decimal data. NUMPROC has no effect on binary data or floating-point
data.
NUMPROC(PFD)
Given X’sd’, where s is the sign representation and d represents the digit, when
you use NUMPROC(PFD), the compiler assumes that the sign in your data is one of
three preferred signs:
Signed positive or 0:
X’C’
Signed negative:
X’D’
Unsigned or alphanumeric:
X’F’
Based on this assumption, the compiler uses whatever sign it is given to process
data. The preferred sign is generated only where necessary (for example, when
unsigned data is moved to signed data). Using the NUMPROC(PFD) option can save
processing time, but you must use preferred signs with your data for correct
processing.
NUMPROC(NOPFD)
When the NUMPROC(NOPFD) compiler option is in effect, the compiler accepts any
valid sign configuration. The preferred sign is always generated in the receiver.
NUMPROC(NOPFD) is less efficient than NUMPROC(PFD), but you should use it whenever
data that does not use preferred signs might exist.
NUMPROC(MIG)
When NUMPROC(MIG) is in effect, the compiler generates code that is similar to that
produced by OS/VS COBOL. This option can be especially useful if you migrate
OS/VS COBOL programs to COBOL for OS/390 & VM.
RELATED REFERENCES
“NUMPROC” on page 283
It can happen that values are passed into your program and assigned to items that
have incompatible data descriptions for those values. For example, nonnumeric
data might be moved or passed into a field that is defined as numeric. Or a signed
number might be passed into a field that is defined as unsigned. In both cases, the
receiving fields contain invalid data. Ensure that the contents of a data item
conform to its PICTURE and USAGE clauses before using the data item in any further
processing steps.
You can use the numeric class test to perform data validation. For example:
Linkage Section.
01 Count-x Pic 999.
. . .
Procedure Division Using Count-x.
If Count-x is numeric then display “Data is good”
The numeric class test checks the contents of a data item against a set of values
that are valid for the particular PICTURE and USAGE of the data item. For example, a
packed-decimal item is checked for hexadecimal values X’0’ through X’9’ in the
digit positions, and for a valid sign value in the sign position (whether separate or
nonseparate).
If NUMCLS(PRIM) is in effect at your installation, use the following table to find the
values that the compiler considers valid for the sign.
If NUMCLS(ALT) is in effect at your installation, use the following table to find the
values that the compiler considers valid for the sign.
RELATED REFERENCES
“NUMPROC” on page 283
42 Programming Guide
Performing arithmetic
You can use any of several COBOL language features to perform arithmetic:
v COMPUTE, ADD, SUBTRACT, MULTIPLY, and DIVIDE statements
v Arithmetic expressions
v Intrinsic functions
v Language Environment callable services
Some arithmetic might be more intuitive using arithmetic statements other than
COMPUTE. For example:
You might also prefer to use the DIVIDE statement (with its REMAINDER phrase) for
division in which you want to process a remainder. The REM intrinsic function also
provides the ability to process a remainder.
Arithmetic expressions
| You can use arithmetic expressions in many (but not all) places in statements
where numeric data items are allowed. For example, you can use arithmetic
expressions as comparands in relation conditions:
If (a + b) > (c - d + 5) Then. . .
Arithmetic expressions can consist of a single numeric literal, a single numeric data
item, or a single intrinsic function reference. They can also consist of several of
these items connected by arithmetic operators. Arithmetic operators are evaluated
in the following order of precedence:
Operators at the same level of precedence are evaluated from left to right;
however, you can use parentheses to change the order of evaluation. Expressions
in parentheses are evaluated before the individual operators are evaluated.
Parentheses, necessary or not, make your program easier to read.
Numeric intrinsic functions return a signed numeric value. They are treated as
temporary numeric data items.
You can use intrinsic functions to perform several different arithmetic operations,
as outlined in the following table.
44 Programming Guide
Nesting functions and arithmetic expressions
You can reference one function as the argument of another. A nested function is
evaluated independently of the outer function, except when determining whether a
mixed function should be evaluated using fixed-point or floating-point
instructions.
In this example, there are only three function arguments: a, b, and the arithmetic
expression (c / d).
You can use the integer special registers as arguments wherever integer arguments
are allowed.
| So for example (considering the first row of the table), if you compile using
| ARITH(COMPAT), CEESDACS returns the same result as ACOS. If you compile using
| ARITH(EXTEND), CEESQACS returns the same result as ACOS.
| 1. RANDOM returns a long (64-bit) floating-point result even if you pass it a 31-digit
| argument and compile using option ARITH(EXTEND).
Both the RANDOM intrinsic function and CEERAN0 service generate random
numbers between zero and one. However, because each uses its own algorithm,
RANDOM and CEERAN0 produce different random numbers from the same seed.
Even for functions that produce the same results, how you use intrinsic functions
and Language Environment callable services differs. The rules for the data types
required for intrinsic function arguments are less restrictive. For numeric intrinsic
functions, you can use arguments that are of any numeric data type. When you
invoke a Language Environment callable service with a CALL statement, however,
you must ensure that the parameters match the numeric data types required by
that service (generally COMP-1 or COMP-2).
This means that if you use INTDATE(LILIAN), you get equivalent results from
COBOL intrinsic functions and Language Environment callable date services.
46 Programming Guide
RELATED CONCEPTS
“Fixed-point versus floating-point arithmetic” on page 49
“Appendix A. Intermediate results and arithmetic precision” on page 559
RELATED TASKS
“Using Language Environment callable services” on page 553
RELATED REFERENCES
“ARITH” on page 262
Finance
Business investment decisions frequently require computing the present value of
expected future cash inflows to evaluate the profitability of a planned investment.
You can use the ANNUITY function in business problems that require you to
determine the amount of an installment payment (annuity) necessary to repay the
principal and interest of a loan. The series of payments is characterized by an
equal amount each period, periods of equal length, and an equal interest rate each
period. The following example shows how you can calculate the monthly payment
required to repay a $15,000 loan in three years at a 12% annual interest rate (36
monthly payments, interest per month = .12/12):
01 Loan Pic 9(9)V99.
01 Payment Pic 9(9)V99.
01 Interest Pic 9(9)V99.
01 Number-Periods Pic 99.
. . .
Compute Loan = 15000
Compute Interest = .12
Compute Number-Periods = 36
Compute Payment =
Loan * Function Annuity((Interest / 12) Number-Periods)
Mathematics
The following COBOL statement demonstrates that you can nest intrinsic
functions, use arithmetic expressions as arguments, and perform previously
complex calculations simply:
Compute Z = Function Log(Function Sqrt (2 * X + 1)) + Function Rem(X 2)
Here in the addend the intrinsic function REM (instead of a DIVIDE statement with a
REMAINDER clause) returns the remainder of dividing X by 2.
Statistics
Intrinsic functions make calculating statistical information easier. Assume you are
analyzing various city taxes and want to calculate the mean, median, and range
(the difference between the maximum and minimum taxes):
01 Tax-S Pic 99v999 value .045.
01 Tax-T Pic 99v999 value .02.
01 Tax-W Pic 99v999 value .035.
01 Tax-B Pic 99v999 value .03.
01 Ave-Tax Pic 99v999.
01 Median-Tax Pic 99v999.
01 Tax-Range Pic 99v999.
. . .
48 Programming Guide
Compute Ave-Tax = Function Mean (Tax-S Tax-T Tax-W Tax-B)
Compute Median-Tax = Function Median (Tax-S Tax-T Tax-W Tax-B)
Compute Tax-Range = Function Range (Tax-S Tax-T Tax-W Tax-B)
Floating-point evaluations
In general, if your arithmetic coding has either of the characteristics listed below, it
is evaluated in floating-point arithmetic:
v An operand or result field is floating point.
A data item is floating point if you code it as a floating-point literal or if you
define it as USAGE COMP-1, USAGE COMP-2, or external floating point (USAGE
DISPLAY with a floating-point PICTURE).
An operand that is a nested arithmetic expression or a reference to a numeric
intrinsic function results in floating-point arithmetic when any of the following
is true:
– An argument in an arithmetic expression results in floating point.
– The function is a floating-point function.
– The function is a mixed function with one or more floating-point arguments.
v An exponent contains decimal places.
An exponent contains decimal places if you use a literal that contains decimal
places, give the item a PICTURE containing decimal places, or use an arithmetic
expression or function whose result has decimal places.
An arithmetic expression or numeric function yields a result with decimal places if
any operand or argument (excluding divisors and exponents) has decimal places.
Fixed-point evaluations
In general, if an arithmetic operation contains neither of the characteristics listed
above for floating point, the compiler will cause it to be evaluated in fixed-point
arithmetic. In other words, arithmetic evaluations are handled as fixed point only if
all the operands are fixed point, the result field is defined to be fixed point, and
none of the exponents represent values with decimal places. Nested arithmetic
expressions and function references must also represent fixed-point values.
Implicit comparisons (no relational operator used) are not handled as a unit,
however; the two comparands are treated separately as to their evaluation in
floating-point or fixed-point arithmetic. In the following example, five arithmetic
expressions are evaluated independently of one another’s attributes, and then are
compared to each other.
evaluate (a + d)
when (b + e) thru c
when (f / g) thru (h * i)
. . .
end-evaluate
RELATED REFERENCES
“Arithmetic expressions in nonarithmetic statements” on page 568
50 Programming Guide
compute report-matrix-col = (emp-count ** .5) + 1
compute report-matrix-col = function sqrt(emp-count) + 1
if report-matrix-tot < function sqrt(emp-count) + 1
To specify the symbols for displaying financial information, use the CURRENCY SIGN
clause (in the SPECIAL-NAMES paragraph in the CONFIGURATION SECTION) with the
PICTURE characters that relate to the symbols. In the following example, the
PICTURE character $ indicates that the currency sign $US is to be used:
Currency Sign is “$US” with Picture Symbol “$”.
. . .
77 Invoice-Amount Pic $$,$$9.99.
. . .
Display “Invoice amount is ” Invoice-Amount.
In this example, if Invoice-Amount contained 1500.00, the display output would be:
Invoice amount is $US1,500.00
By using more than one CURRENCY SIGN clause in your program, you can allow for
multiple currency signs to be displayed.
You can use a hexadecimal literal to indicate the currency sign value. This could be
useful if the data-entry method for the source program does not allow the entry of
the intended characters easily. The following example shows the hex value X’9F’
used as the currency sign:
Currency Sign X'9F' with Picture Symbol 'U'.
. . .
01 Deposit-Amount Pic UUUUU9.99.
If there is no corresponding character for the euro sign on your keyboard, you
need to specify it as a hexadecimal value in the CURRENCY SIGN clause. The
hexadecimal value for the euro sign is either X’9F’ or X’5A’ depending on the code
page in use, as shown in the following table.
Modified
Code page Applicable countries from Euro sign
IBM-1140 USA, Canada, Netherlands, Portugal, IBM-037 X’9F’
Australia, New Zealand
IBM-1141 Austria, Germany IBM-273 X’9F’
IBM-1142 Denmark, Norway IBM-277 X’5A’
The exchange rate used in this example is for illustrative purposes only.
52 Programming Guide
Chapter 4. Handling tables
A table is a collection of data items that have the same description, such as account
totals or monthly averages. A table is the COBOL equivalent of an array of
elements. It consists of a table name and subordinate items called table elements.
In the example above, SAMPLE-TABLE-ONE is the group item that contains the table.
TABLE-COLUMN names the table element of a one-dimensional table that occurs three
times.
Rather than define repetitious items as separate, consecutive entries in the DATA
DIVISION, you can use the OCCURS clause in the DATA DIVISION entry to define a
table. This practice has these advantages:
v The code clearly shows the unity of the items (the table elements).
v You can use subscripts and indexes to refer to the table elements.
v You can easily repeat data items.
Tables are important for increasing the speed of a program, especially one that
looks up records.
RELATED TASKS
“Defining a table (OCCURS)”
“Referring to an item in a table” on page 55
“Putting values into a table” on page 58
“Nesting tables” on page 54
“Creating variable-length tables (DEPENDING ON)” on page 62
“Searching a table” on page 65
“Processing table items using intrinsic functions” on page 67
“Handling tables efficiently” on page 539
The table element definition (which includes the OCCURS clause) is subordinate to
the group item that contains the table. The OCCURS clause cannot appear in a
level-01 description.
RELATED REFERENCES
OCCURS clause (IBM COBOL Language Reference)
Nesting tables
To create a two-dimensional table, define a one-dimensional table in each
occurrence of another one-dimensional table. For example:
Subscripting
In a two-dimensional table, the two subscripts correspond to the row and column
numbers. In a three-dimensional table, the three subscripts correspond to the
depth, row, and column numbers.
54 Programming Guide
TABLE-COLUMN (2, 2, 1)
TABLE-COLUMN (2 2 1)
In either table reference, the first value (2) refers to the second occurrence within
TABLE-DEPTH, the second value (2) refers to the second occurrence within TABLE-ROW,
and the third value (1) refers to the first occurrence within TABLE-COLUMN.
Indexing
Consider the following three-dimensional table, SAMPLE-TABLE-FOUR:
01 SAMPLE-TABLE-FOUR
05 TABLE-DEPTH OCCURS 3 TIMES INDEXED BY INX-A.
10 TABLE-ROW OCCURS 4 TIMES INDEXED BY INX-B.
15 TABLE-COLUMN OCCURS 8 TIMES INDEXED BY INX-C PIC X(8).
RELATED REFERENCES
OCCURS clause (IBM COBOL Language Reference)
Subscripting
The lowest possible subscript value is 1, which points to the first occurrence of the
table element. In a one-dimensional table, the subscript corresponds to the row
number.
If a data item with a literal subscript is of fixed length, the compiler resolves the
location of the data item.
When you use a data name as a variable subscript, you must describe the data
name as an elementary numeric integer. The most efficient format is COMPUTATIONAL
(COMP) with a PICTURE size smaller than five digits. You cannot use a subscript with
a data name that is used as a subscript.
The code generated for the application resolves the location of a variable subscript
at run time.
You can change part of a table element rather than the whole element. Simply refer
to the character position and length of the substring to be changed within the
subscripted element. For example:
01 ANY-TABLE.
05 TABLE-ELEMENT PIC X(10)
OCCURS 3 TIMES
VALUE “ABCDEFGHIJ”.
. . .
MOVE “??” TO TABLE-ELEMENT (1) (3 : 2).
The MOVE statement moves the value ?? into table element number 1, beginning at
character position 3, for a length of 2:
RELATED TASKS
“Indexing” on page 57
56 Programming Guide
“Putting values into a table” on page 58
“Searching a table” on page 65
“Handling tables efficiently” on page 539
Indexing
You can create an index either with a particular table (using OCCURS INDEXED BY) or
separately (using USAGE IS INDEX).
For example:
05 TABLE-ITEM PIC X(8)
OCCURS 10 INDEXED BY INX-A.
The compiler calculates the value contained in the index as the occurrence number
(subscript) minus 1, multiplied by the length of the table element. Therefore, for
the fifth occurrence of TABLE-ITEM, the binary value contained in INX-A is (5 - 1) * 8,
or 32.
You can use this index to index another table only if both table descriptions have
the same number of table elements, and the table elements are the same length.
If you use USAGE IS INDEX to create an index, you can use the index data item with
any table. For example:
77 INX-B USAGE IS INDEX.
. . .
PERFORM VARYING INX-B FROM 1 BY 1 UNTIL INX-B > 10
DISPLAY TABLE-ITEM (INX-B)
. . .
END-PERFORM.
INX-B is used to traverse table TABLE-ITEM above, but could be used to traverse
other tables also.
Initialize the index name with a SET, PERFORM VARYING, or SEARCH ALL statement.
You can then also use it in SEARCH or relational condition statements. To change the
value, use a PERFORM, SEARCH, or SET statement.
Use the SET statement to assign to an index the value that you stored in the index
data item defined by USAGE IS INDEX. For example, when you load records into a
variable-length table, you can store the index value of the last record read in a data
item defined as USAGE IS INDEX. Then you can test for the end of the table by
comparing the current index value with the index value of the last record. This
technique is useful when you look through or process the table.
Because you are comparing a physical displacement, you can use index data items
only in SEARCH and SET statements or for comparisons with indexes or other index
data items. You cannot use index data items as subscripts or indexes.
RELATED TASKS
“Subscripting” on page 56
“Putting values into a table” on page 58
RELATED REFERENCES
INDEXED BY phrase (IBM COBOL Language Reference)
INDEX phrase (IBM COBOL Language Reference)
To load a table, use the PERFORM statement and either subscripting or indexing.
When reading data to load your table, test to make sure that the data does not
exceed the space allocated for the table. Use a named value (rather than a literal)
for the item count. Then, if you make the table bigger, you need to change only
one value, instead of all references to a literal.
RELATED REFERENCES
PERFORM with VARYING phrase (IBM COBOL Language Reference)
The INITIALIZE statement cannot load a variable-length table (one that was defined
using OCCURS DEPENDING ON).
RELATED REFERENCES
INITIALIZE statement (IBM COBOL Language Reference)
58 Programming Guide
Define static values in WORKING-STORAGE in one of these ways:
v Initialize each table item individually.
v Initialize an entire table at the 01 level.
v Initialize all occurrences of a given table element to the same value.
(In this example, the items could all be initialized with one VALUE clause at the 01
level, because each item was being initialized to the same value.)
For example:
01 TABLE-ONE VALUE “1234”.
05 TABLE-TWO OCCURS 4 TIMES PIC X.
The above code causes all the X elements (1 through 5) to be initialized to AA, all
the Y elements (1 through 5) to be initialized to 19, and all the Z elements (1
through 5) to be initialized to BB. T-OBJ is then set to 3.
60 Programming Guide
Example: PERFORM and indexing
This example traverses an error flag table using indexing until an error code that
has been set is found. If an error code is found, the corresponding error message is
moved to a print report field.
. . .
***********************************************************
*** E R R O R F L A G T A B L E ***
***********************************************************
01 Error-Flag-Table Value Spaces.
88 No-Errors Value Spaces.
05 Type-Error Pic X.
05 Shift-Error Pic X.
05 Home-Code-Error Pic X.
05 Work-Code-Error Pic X.
05 Name-Error Pic X.
05 Initials-Error Pic X.
05 Duplicate-Error Pic X.
05 Not-Found-Error Pic X.
01 Filler Redefines Error-Flag-Table.
05 Error-Flag Occurs 8 Times
Indexed By Flag-Index Pic X.
***********************************************************
*** E R R O R M E S S A G E T A B L E ***
***********************************************************
01 Error-Message-Table.
05 Filler Pic X(25) Value
“Transaction Type Invalid”.
05 Filler Pic X(25) Value
“Shift Code Invalid”.
05 Filler Pic X(25) Value
“Home Location Code Inval.”.
05 Filler Pic X(25) Value
“Work Location Code Inval.”.
05 Filler Pic X(25) Value
“Last Name - Blanks”.
05 Filler Pic X(25) Value
“Initials - Blanks”.
05 Filler Pic X(25) Value
“Duplicate Record Found”.
05 Filler Pic X(25) Value
“Commuter Record Not Found”.
01 Filler Redefines Error-Message-Table.
05 Error-Message Occurs 8 Times
Indexed By Message-Index Pic X(25).
. . .
PROCEDURE DIVISION.
. . .
Set Flag-Index To 1
Perform Until No-Errors
Search Error-Flag
When Error-Flag (Flag-Index) = Error-On
Move Space To Error-Flag (Flag-Index)
Set Message-Index To Flag-Index
Move Error-Message (Message-Index) To
Print-Message
Perform 260-Print-Report
End-Search
End-Perform
. . .
In this example, X is called the ODO subject, and Y is the ODO object.
If you want to move REC-1 (the sending item in this case) to REC-2, the length of
REC-1 is determined immediately before the move, using the current value in
FIELD-1. If the content of FIELD-1 conforms to its PICTURE (that is, if FIELD-1
contains an external decimal item), the move can proceed based on the actual
length of REC-1. Otherwise, the result is unpredictable. You must ensure that the
ODO object has the correct value before you initiate the move.
When you do a move to REC-1 (the receiving item in this case), the length of REC-1
is determined using the maximum number of occurrences. In this example, that
would be five occurrences of FIELD-2, plus FIELD-1, for a length of 26 bytes.
In this case, you need not set the ODO object (FIELD-1) before referencing REC-1 as
a receiving item. However, the sending field’s ODO object (not shown) must be set
to a valid numeric value between 1 and 5 for the ODO object of the receiving field
to be validly set by the move.
However, if you do a move to REC-1 (again the receiving item) where REC-1 is
followed by a variably located group (a type of complex ODO), the actual length of
REC-1 is calculated immediately before the move. In the following example, REC-1
and REC-2 are in the same record, but REC-2 is not subordinate to REC-1 and is
therefore variably located:
62 Programming Guide
01 MAIN-AREA
03 REC-1.
05 FIELD-1 PIC 9.
05 FIELD-3 PIC 9.
05 FIELD-2 OCCURS 1 TO 5 TIMES
DEPENDING ON FIELD-1 PIC X(05).
03 REC-2.
05 FIELD-4 OCCURS 1 TO 5 TIMES
DEPENDING ON FIELD-3 PIC X(05).
When you do a MOVE to REC-1 in this case, the actual length of REC-1 is calculated
immediately before the move using the current value of the ODO object (FIELD-1).
The compiler issues a message letting you know that the actual length was used.
This case requires that you set the value of the ODO object before using the group
item as a receiving field.
The following example shows how to define a variable-length table when the ODO
object (here LOCATION-TABLE-LENGTH) is outside the group.
DATA DIVISION.
FILE SECTION.
FD LOCATION-FILE
RECORDING MODE F
BLOCK 0 RECORDS
RECORD 80 CHARACTERS
LABEL RECORD STANDARD.
01 LOCATION-RECORD.
05 LOC-CODE PIC XX.
05 LOC-DESCRIPTION PIC X(20).
05 FILLER PIC X(58).
. . .
WORKING-STORAGE SECTION.
01 FLAGS.
05 LOCATION-EOF-FLAG PIC X(5) VALUE SPACE.
88 LOCATION-EOF VALUE “FALSE”.
01 MISC-VALUES.
05 LOCATION-TABLE-LENGTH PIC 9(3) VALUE ZERO.
05 LOCATION-TABLE-MAX PIC 9(3) VALUE 100.
*****************************************************************
*** L O C A T I O N T A B L E ***
*** FILE CONTAINS LOCATION CODES. ***
*****************************************************************
01 LOCATION-TABLE.
05 LOCATION-CODE OCCURS 1 TO 100 TIMES
DEPENDING ON LOCATION-TABLE-LENGTH PIC X(80).
RELATED CONCEPTS
“Appendix B. Complex OCCURS DEPENDING ON” on page 569
RELATED TASKS
“Assigning values to a variable-length table” on page 64
“Loading a variable-length table”
COBOL for OS/390 & VM Compiler and Run-Time Migration Guide
RELATED REFERENCES
OCCURS DEPENDING ON clause (IBM COBOL Language Reference)
“CMPR2” on page 264
If the ODO object has a VALUE clause, it is logically initialized after the ODO subject
has been initialized. For example, in the following code
01 TABLE-THREE VALUE “3ABCDE”.
05 X PIC 9.
05 Y OCCURS 5 TIMES
DEPENDING ON X PIC X.
the ODO subject Y(1) is initialized to A, Y(2) to B, . . ., Y(5) to E, and finally the
ODO object X is initialized to 3. Any subsequent reference to TABLE-THREE (such as
in a DISPLAY statement) refers to the first three elements, Y(1) through Y(3).
RELATED TASKS
COBOL for OS/390 & VM Compiler and Run-Time Migration Guide
64 Programming Guide
RELATED REFERENCES
OCCURS DEPENDING ON clause (IBM COBOL Language Reference)
“CMPR2” on page 264
Searching a table
COBOL provides two search techniques for tables: serial and binary.
To do serial searches, use SEARCH and indexing. For variable-length tables, you can
use PERFORM with subscripting or indexing.
A binary search can be considerably more efficient than a serial search. For a serial
search, the number of comparisons is of the order of n, the number of entries in
the table. For a binary search, the number of comparisons is only of the order of
the logarithm (base 2) of n. A binary search, however, requires that the table items
already be sorted.
RELATED TASKS
“Doing a serial search (SEARCH)”
“Doing a binary search (SEARCH ALL)” on page 66
The conditions in the WHEN option are evaluated in the order in which they appear:
v If none of the conditions is satisfied, the index is increased to correspond to the
next table element, and the WHEN conditions are evaluated again.
v If one of the WHEN conditions is satisfied, the search ends. The index remains
pointing to the table element that satisfied the condition.
v If the entire table has been searched and no conditions were met, the AT END
imperative statement is executed if there is one. If you do not use AT END,
control passes to the next statement in your program.
You can reference only one level of a table (a table element) with each SEARCH
statement. To search multiple levels of a table, use nested SEARCH statements.
Delimit each nested SEARCH statement with END-SEARCH.
If the found condition comes after some intermediate point in the table, you can
speed up the search. Use the SET statement to set the index to begin the search
after that point.
Arranging the table so that the data used most often is at the beginning also
enables more efficient serial searching. If the table is large and is presorted, a
binary search is more efficient.
RELATED REFERENCES
SEARCH statement (IBM COBOL Language Reference)
To use the SEARCH ALL statement, your table must already be ordered on the key or
keys coded in the OCCURS clause. You can use any key in the WHEN condition, but
you must test all preceding data names in the KEY option, if any. The test must be
an equal-to condition, and the KEY data-name must be either the subject of the
condition or the name of a conditional variable with which the tested
condition-name is associated. The WHEN condition can also be a compound
condition, formed from simple conditions with AND as the only logical connective.
The key and its object of comparison must be compatible.
RELATED REFERENCES
SEARCH statement (IBM COBOL Language Reference)
66 Programming Guide
Example: binary search
Suppose you define a table that contains 90 elements of 40 bytes each, with three
keys. The primary and secondary keys (KEY-1 and KEY-2) are in ascending order,
but the least significant key (KEY-3) is in descending order:
01 TABLE-A.
05 TABLE-ENTRY OCCURS 90 TIMES
ASCENDING KEY-1, KEY-2
DESCENDING KEY-3
INDEXED BY INDX-1.
10 PART-1 PIC 99.
10 KEY-1 PIC 9(5).
10 PART-2 PIC 9(6).
10 KEY-2 PIC 9(4).
10 PART-3 PIC 9(18).
10 KEY-3 PIC 9(5).
If an entry is found in which the three keys are equal to the given values (VALUE-1,
VALUE-2, and VALUE-3), PART-1 of that entry will be moved to OUTPUT-AREA. If
matching keys are not found in any of the entries in TABLE-A, the NOENTRY routine
is performed.
You might often need to process the data in tables iteratively. For intrinsic
functions that accept multiple arguments, you can use the ALL subscript to
reference all the items in the table or a single dimension of the table. The iteration
is handled automatically, making your code shorter and simpler.
You can mix scalars and array arguments for functions that accept multiple
arguments:
Compute Table-Median = Function Median(Arg1 Table-One(ALL))
RELATED TASKS
“Using intrinsic functions (built-in functions)” on page 31
RELATED REFERENCES
Intrinsic functions (IBM COBOL Language Reference)
Assuming that Table-Two is a 2x3x2 array, the statement above causes the
following elements to be summed:
Table-Two(1,3,1)
Table-Two(1,3,2)
Table-Two(2,3,1)
Table-Two(2,3,2)
68 Programming Guide
Chapter 5. Selecting and repeating program actions
Use COBOL control language to choose program actions based on the outcome of
logical tests, to iterate over selected parts of your program and data, and to
identify statements to be performed as a group. These controls include:
v IF statement
v EVALUATE statement
v Switches and flags
v PERFORM statement
RELATED TASKS
“Selecting program actions”
“Repeating program actions” on page 76
The IF and EVALUATE statements in COBOL test one or more data items by means
of a conditional expression.
RELATED TASKS
“Coding a choice of actions”
“Coding conditional expressions” on page 73
RELATED REFERENCES
IF statement (IBM COBOL Language Reference)
EVALUATE statement (IBM COBOL Language Reference)
When one of the processing choices is no action, code the IF statement with or
without ELSE. Because the ELSE clause is optional, you can code the following:
IF condition-q
statement-1
END-IF
This coding is suitable for simple programming cases. For complex logic, you
probably need to use the ELSE clause. For example, suppose you have nested IF
statements with an action for only one of the processing choices; you could use the
ELSE clause and code the null branch of the IF statement with the CONTINUE
statement:
Use the EVALUATE statement to code a choice among three or more possible
conditions instead of just two. The EVALUATE statement is an expanded form of the
IF statement that allows you to avoid nesting IF statements for such coding, a
common source of logic errors and debugging problems.
With the EVALUATE statement, you can test any number of conditions in a single
statement and have separate actions for each. In structured programming terms,
this is a case structure. It can also be thought of as a decision table.
RELATED TASKS
“Coding conditional expressions” on page 73
“Using the EVALUATE statement” on page 71
“Using nested IF statements”
Use nested IF statements sparingly. The logic can be difficult to follow, although
explicit scope terminators and proper indentation help.
The following figure shows the logic structure for nested IF statements.
70 Programming Guide
RELATED TASKS
“Coding a choice of actions” on page 69
RELATED REFERENCES
Explicit scope terminators (IBM COBOL Language Reference)
You can code the EVALUATE statement to handle the case where multiple conditions
lead to the same processing by using the THRU phrase and by using multiple WHEN
statements.
When evaluated, each pair of selection subjects and selection objects must belong
to the same class (numeric, character, CONDITION TRUE or FALSE).
RELATED TASKS
“Coding a choice of actions” on page 69
Example: EVALUATE using multiple WHEN statements: You can use multiple
WHEN statements when several conditions lead to the same processing action. This
gives you more flexibility than using the THRU phrase, because the conditions do
not have to evaluate to values that fall in a range or evaluate to alphanumeric
values.
EVALUATE MARITAL-CODE
WHEN “M”
ADD 2 TO PEOPLE-COUNT
WHEN “S”
WHEN “D”
WHEN “W”
ADD 1 TO PEOPLE-COUNT
END-EVALUATE
72 Programming Guide
Configuration Section.
Source-Computer. IBM-390.
Data Division.
Working-Storage Section.
01 Age Pic 999.
01 Sex Pic X.
01 Description Pic X(15).
01 A Pic 999.
01 B Pic 9999.
01 C Pic 9999.
01 D Pic 9999.
01 E Pic 99999.
01 F Pic 999999.
Procedure Division.
PN01.
Evaluate True Also True
When Age < 13 Also Sex = “M”
Move “Young Boy” To Description
When Age < 13 Also Sex = “F”
Move “Young Girl” To Description
When Age > 12 And Age < 20 Also Sex = “M”
Move “Teenage Boy” To Description
When Age > 12 And Age < 20 Also Sex = “F”
Move “Teenage Girl” To Description
When Age > 19 Also Sex = “M”
Move “Adult Man” To Description
When Age > 19 Also Sex = “F”
Move “Adult Woman” To Description
When Other
Move “Invalid Data” To Description
End-Evaluate
Evaluate True Also True
When A + B < 10 Also C = 10
Move “Case 1” To Description
When A + B > 50 Also C = ( D + E ) / F
Move “Case 2” To Description
When Other
Move “Case Other” To Description
End-Evaluate
Stop Run.
RELATED TASKS
“Defining switches and flags” on page 74
“Resetting switches and flags” on page 75
“Checking for incompatible data (numeric class test)” on page 42
Flags and switches make your code easier to change. If you need to change the
values for a condition, you have to change only the value of that level-88
condition-name.
For example, suppose a program uses a condition-name to test a field for a given
salary range. If the program must be changed to check for a different salary range,
you need to change only the value of the condition-name in the DATA DIVISION.
You do not need to make changes in the PROCEDURE DIVISION.
RELATED TASKS
“Defining switches and flags”
“Resetting switches and flags” on page 75
To test for more than two values, as flags, assign more than one condition name to
a field by using multiple level-88 items.
The reader can easily follow your code if you choose meaningful condition names
and if the values assigned have some association with logical values.
“Example: switches”
“Example: flags” on page 75
Example: switches
To test for an end-of-file condition for an input file named Transaction-File, you
could use the following data definitions:
WORKING-STORAGE Section.
01 Switches.
05 Transaction-EOF-Switch Pic X value space.
88 Transaction-EOF value “y”.
74 Programming Guide
If Transaction-EOF Then
Perform Print-Report-Summary-Lines
Example: flags
Consider a program that updates a master file. The updates are read from a
transaction file. The transaction file’s records contain a field for the function to be
performed: add, change, or delete. In the record description of the input file code a
field for the function code using level-88 items:
01 Transaction-Input Record
05 Transaction-Type Pic X.
88 Add-Transaction Value “A”.
88 Change-Transaction Value “C”.
88 Delete-Transaction Value “D”.
The code in the PROCEDURE DIVISION for testing these condition-names might look
like this:
Evaluate True
When Add-Transaction
Perform Add-Master-Record-Paragraph
When Change-Transaction
Perform Update-Exisitng-Record-Paragraph
When Delete-Transaction
Perform Delete-Master-Record-Paragraph
End-Evaluate
When you use the SET condition-name TO TRUE statement, the switch or flag is set
back to the original value that was assigned in its data description.
For a level-88 item with multiple values, SET condition-name TO TRUE assigns the
first value (here, A):
88 Record-is-Active Value “A” “O” “S”
Using the SET statement and meaningful condition-names makes it easy for the
reader to follow your code.
The following example shows how to assign a value for a field in an output record
based on the transaction code of an input record.
This code resets the switch to indicate that the end of the file has not been reached.
Use the PERFORM statement to loop (repeat the same code) a set number of times or
to loop based on the outcome of a decision.
RELATED TASKS
“Choosing inline or out-of-line PERFORM”
“Coding a loop” on page 77
“Coding a loop through a table” on page 78
“Executing multiple paragraphs or sections” on page 79
RELATED REFERENCES
PERFORM statement (IBM COBOL Language Reference)
76 Programming Guide
To determine whether to code an inline or out-of-line PERFORM statement, consider
the following questions:
v Is the PERFORM statement used from several places?
Use out-of-line PERFORM when you use the same piece of code from several
places in your program.
v Which placement of the statement will be easier to read?
Use an out-of-line PERFORM if the logical flow of the program will be less clear
because the PERFORM extends over several screens. If, however, the PERFORM
paragraph is short, an inline PERFORM can save the trouble of skipping around in
the code.
v What are the efficiency tradeoffs?
Avoid the overhead of branching around an out-of-line PERFORM if performance is
an issue. But remember, even out-of-line PERFORM coding can improve code
optimization, so efficiency gains should not be overemphasized.
In the 1974 COBOL standard, the PERFORM statement is out-of-line and thus requires
an explicit branch to a separate paragraph and has an implicit return. If the
performed paragraph is in the subsequent sequential flow of your program, it is
also executed in that flow of the logic. To avoid this additional execution, you
must place the paragraph outside the normal sequential flow (for example, after
the GOBACK) or code a branch around it.
Coding a loop
Use the PERFORM . . . TIMES statement to execute a paragraph a certain number of
times:
PERFORM 010-PROCESS-ONE-MONTH 12 TIMES
INSPECT . . .
Use the PERFORM . . . WITH TEST AFTER . . . UNTIL if you want to execute the
paragraph at least once and then test before any subsequent execution. This
statement is equivalent to the do-until structure:
In the following example, the implicit WITH TEST BEFORE phrase provides a
do-while structure:
PERFORM 010-PROCESS-ONE-MONTH
UNTIL MONTH GREATER THAN 12
INSPECT . . .
When control reaches the PERFORM statement, the condition (MONTH EQUAL DECEMBER)
is tested. If the condition is satisfied, control is transferred to the INSPECT
statement. If the condition is not satisfied, 010-PROCESS-ONE-MONTH is executed, and
the condition is tested again. This cycle continues until the condition tests as true.
(To make your program easier to read, you might want to code the WITH TEST
BEFORE clause.)
Thus you use the PERFORM statement to control a loop through a table. You can use
either of the following forms:
PERFORM . . . WITH TEST AFTER . . . VARYING . . . UNTIL . . .
PERFORM . . . [WITH TEST BEFORE] . . . VARYING . . . UNTIL .
The following code shows an example of looping through a table to check for
invalid data:
78 Programming Guide
PERFORM TEST AFTER VARYING WS-DATA-IX
FROM 1 BY 1
UNTIL WS-DATA-IX = 12
IF WS-DATA (WS-DATA-IX) EQUALS SPACES
SET SERIOUS-ERROR TO TRUE
DISPLAY ELEMENT-NUM-MSG5
END-IF
END-PERFORM
INSPECT . . .
In the code above, when control reaches the PERFORM statement, WS-DATA-IX is set
equal to 1 and the PERFORM statement is executed. Then the condition
(WS-DATA-IX = 12) is tested. If the condition is true, control drops through to the
INSPECT statement. If it is false, WS-DATA-IX is increased by 1, the PERFORM statement
is executed, and the condition is tested again. This cycle of execution and testing
continues until WS-DATA-IX is equal to 12.
In terms of the application, this loop controls input-checking for the 12 fields of
item WS-DATA. Empty fields are not allowed, and this section of code loops through
and issues error messages as appropriate.
Intrinsic functions can make the coding of the iterative processing of tables simpler
and easier.
RELATED TASKS
“Processing table items using intrinsic functions” on page 67
The STRING statement transfers data items into the receiving item in the order you
indicate. In the STRING statement you can also specify the following:
v Delimiters that cause a sending field to be ended and another to be started
v Actions to be taken when the single receiving field is filled before all of the
sending characters have been processed (ON OVERFLOW condition)
“Example: STRING statement”
RELATED TASKS
“Handling errors in joining and splitting strings” on page 190
RELATED REFERENCES
STRING statement (IBM COBOL Language Reference)
The record RCD-01 contains the following information (the symbol º indicates a
blank space):
J.B.ºSMITHººººº
444ºSPRINGºST.,ºCHICAGO,ºILL.ºººººº
A14275
$4,736.85
$2,400.00
09/22/76
$2,336.85
10/22/76
In the PROCEDURE DIVISION, the programmer initializes RPT-LINE to SPACES and sets
LINE-POS, the data item to be used as the POINTER field, to 4. (By coding the
POINTER phrase of the STRING statement, you can use the explicit pointer field to
control placement of data in the receiving field.) Then, the programmer codes this
STRING statement:
STRING
LINE-NO SPACE CUST-INFO INV-NO SPACE DATE-DUE SPACE
DELIMITED BY SIZE
BAL-DUE
DELIMITED BY DEC-POINT
INTO RPT-LINE
WITH POINTER LINE-POS.
Item Positions
LINE-NO 4-8
Space 9
CUST-INFO 10 - 59
INV-NO 60 - 65
Space 66
DATE-DUE 67 - 74
Space 75
Portion of BAL-DUE that precedes the decimal point 76 - 81
After the STRING statement is performed, the value of LINE-POS is 82, and RPT-LINE
appears as shown below.
82 Programming Guide
Splitting data items (UNSTRING)
Use the UNSTRING statement to split one sending field into several receiving fields.
One UNSTRING statement can save you several MOVE statements.
RELATED TASKS
“Handling errors in joining and splitting strings” on page 190
COBOL for OS/390 & VM Compiler and Run-Time Migration Guide
RELATED REFERENCES
“CMPR2” on page 264
UNSTRING statement (IBM COBOL Language Reference)
Before issuing the UNSTRING statement, the programmer places the value 3 in
CHAR-CT (the POINTER field) to avoid working with the two control characters in
INV-RCD. A period (.) is placed in DBY-1 for use as a delimiter, and the value 0
(zero) is placed in FLDS-FILLED (the TALLYING field). The data is then read into
INV-RCD, as shown below.
84 Programming Guide
4. Positions 31 through 33 are placed in INV-CLASS. The delimiter is a SPACE, but
because no field has been defined as a receiving area for delimiters, the SPACE
in position 34 is bypassed.
5. Positions 35 through 40 (475120) are examined and placed in M-UNITS. The
value 6 is placed in CTR-3. The delimiter is a SPACE, but because no field has
been defined as a receiving area for delimiters, the SPACE in position 41 is
bypassed.
6. Positions 42 through 46 (00122) are placed in FIELD-A and right-justified in the
area. The high-order digit position is filled with a 0 (zero). The delimiter is a
SPACE, but because no field has been defined as a receiving area for delimiters,
the SPACE in position 47 is bypassed.
7. Positions 48 through 53 (000379) are placed in DISPLAY-DOLS. The period (.)
delimiter character in DBY-1 is placed in DLTR-2, and the value 6 is placed in
CTR-4.
8. Because all receiving fields have been acted on and two characters of data in
INV-RCD have not been examined, the ON OVERFLOW exit is taken, and execution
of the UNSTRING statement is completed.
After the UNSTRING statement is performed, the fields contain the values shown
below.
Field Value
DISPLAY-REC 707890 FOUR-PENNY-NAILS 000379
WORK-REC 475120000122BBA
CHAR-CT (the POINTER field) 55
FLDS-FILLED (the TALLYING field) 6
RELATED REFERENCES
Nonnumeric literals (IBM COBOL Language Reference)
As this example shows, in parentheses immediately following the data item you
code two values separated by a colon:
v Ordinal position (from the left) of the character you want the substring to start
with
v Length of the desired substring
86 Programming Guide
The length is optional. If you omit the length, the substring extends to the end of
the item. Omit the length when possible as a simpler and less error-prone coding
technique.
You can code either of the two values as a variable or as an arithmetic expression.
You can also refer to substrings of table entries, including variable-length entries.
Both numbers in the reference modifier must have a value of at least 1. Their sum
should not exceed the total length of the data item by more than 1 so that you do
not reference beyond the end of the desired substring.
The following options detect out-of-range reference modifiers, and flag violations
with a run-time message:
v SSRANGE compiler option
v CHECK run-time option
RELATED CONCEPTS
“Reference modifiers”
RELATED TASKS
“Referring to an item in a table” on page 55
RELATED REFERENCES
“SSRANGE” on page 294
Reference modification (IBM COBOL Language Reference)
Function definitions (IBM COBOL Language Reference)
Reference modifiers
Assume that you want to retrieve the current time from the system and display its
value in an expanded format. You can retrieve the current time with the ACCEPT
statement, which returns the hours, minutes, seconds, and hundredths of seconds
in this format:
HHMMSSss
However, you might prefer to view the current time in this format:
HH:MM:SS
Without reference modifiers, you would have to define data items for both formats.
You would also have to write code to convert from one format to the other.
With reference modifiers, you do not need to provide names for the subfields that
describe the TIME elements. The only data definition you need is for the time as
returned by the system. For example:
01 REFMOD-TIME-ITEM PIC X(8).
RELATED TASKS
“Referring to substrings of data items” on page 86
The program counts the number of leading spaces and, using arithmetic
expressions in a reference modifier, moves the right-justified characters into
another field, justified to the left:
MOVE SPACES TO LEFTY
MOVE ZERO TO I
INSPECT RIGHTY
TALLYING I FOR LEADING SPACE.
IF I IS LESS THAN LENGTH OF RIGHTY THEN
MOVE RIGHTY ( I + 1 : LENGTH OF RIGHTY - I ) TO LEFTY
END-IF
The MOVE statement transfers characters from RIGHTY, beginning at the position
computed as I + 1 for a length that is computed as LENGTH OF RIGHTY - I, into the
field LEFTY.
88 Programming Guide
RELATED REFERENCES
INTEGER-PART (IBM COBOL Language Reference)
INTEGER (IBM COBOL Language Reference)
RELATED REFERENCES
INSPECT statement (IBM COBOL Language Reference)
In the following example, the INSPECT statement is used to examine and replace
characters in data item DATA-2. The number of times a leading 0 occurs in the data
item is accumulated in COUNTR. Every instance of the character A following the first
instance of the character C is replaced by the character 2.
77 COUNTR PIC 9 VALUE ZERO.
01 DATA-2 PIC X(11).
. . .
INSPECT DATA-2
TALLYING COUNTR FOR LEADING “0”
REPLACING FIRST “A” BY “2” AFTER INITIAL “C”
In the following example, the INSPECT statement is used to examine and replace
characters in data item DATA-3. Every character in the data item preceding the first
instance of a quote (“) is replaced by the character 0.
77 COUNTR PIC 9 VALUE ZERO.
01 DATA-3 PIC X(8).
. . .
INSPECT DATA-3
REPLACING CHARACTERS BY ZEROS BEFORE INITIAL QUOTE
The following example shows the use of INSPECT CONVERTING with AFTER and
BEFORE phrases to examine and replace characters in data item DATA-4. All