QUARTLY-REVENUE OCCURS 4 TIMES PIC 9(7)V99. Will allocate the following: QUARTLY-REVENUE (1) QUARTLY-REVENUE (2) QUARTLY-REVENUE (3) QUARTLY-REVENUE (4)

05 QUARTLY-REVENUE OCCURS 4 TIMES PIC 9(7)V99. Will allocate the following: QUARTLY-REVENUE (1) QUARTLY-REVENUE (2) QUARTLY-REVENUE (3) QUARTLY-REVENUE (4)

Each occurrence is referenced using the subscript syntax (a numeric literal, arithmetic expression or numeric identifier enclosed within parenthesis) shown in the diagram. The OCCURS clause may be used at the group level too, in which case the entire group structure repeats, as follows:

12 Other programming languages with which you might be familiar refer to this sort of structure as an array.

05 X OCCURS 3 TIMES. 10 A PIC X(1). 10 B PIC X(1). 10 C PIC X(1).

C (3) See sections 6.1.1 (Table References), 6.38 (SEARCH), 6.40 (SORT) as well as item # 28 below for more information

B (3)

about tables.

13. The optional DEPENDING ON clause can be added to an OCCURS to create a variable-length table. Such tables will

be allocated out to the maximum size specified as integer-2. At execution time the value of identifier-5 will determine how many of the table elements are accessible.

14. The OCCURS clause cannot be specified in a data description entry that has a level number of 01, 66, 77, or 88.

15. VALUE specifies an initial compilation-time value that will be assigned to the storage occupied by the data item in the program object code generated by the compiler. If the optional “ALL” clause is used, it may only be used with an alphanumeric literal value; the value will be repeated as needed to completely fill the data item. Here are

some examples with and without ALL: PIC X(5) VALUE “A” – will have the value “A”,SPACE,SPACE,SPACE,SPACE PIC X(5) VALUE ALL “A” – will have the value “A”,”A”,”A”,”A”,”A” PIC 9(3) VALUE 1 – will have the value 001 PIC 9(3) VALUE ALL “1” – will have the value 111

16. The ASCENDING KEY, DESCENDING KEY and INDEXED BY clauses will be discussed in section 6.39 (SEARCH).

17. The BASED and ANY LENGTH clauses cannot be used together.

18. The JUSTIFIED RIGHT clause, valid only on an alphabetic (PIC A) or alphanumeric (PIC X) item, will cause values shorter than the length of the data item to be right-justified and space-filled when they are MOVEd into the data item.

19. Data items declared with BASED are allocated no storage at compilation time. At run-time, the ALLOCATE verb is used to allocate space for and (optionally) initialize such items.

20. Data items declared with the ANY LENGTH attribute have no fixed compile-time length. Such items may only be defined in the LINKAGE SECTION as they may only serve as subroutine argument descriptions. ANY LENGTH items must have a PICTURE clause that specifies exactly one A, X or 9 symbol.

21. The BLANK WHEN ZERO clause, when used on a numeric item, will cause that item’s value to be automatically transformed into SPACES if a value of 0 is ever MOVEd to the item.

22. The REDEFINES clause causes identifier-1 to occupy the same physical storage space as identifier-2, so that storage may be defined in a different manner with a (probably) different structure. The following must all be true in order to use REDEFINES:

a. The level number of identifier-2 must be the same as that of identifier-1.

b. The level number of identifier-2 (and identifier-1) cannot be 66, 77, 78 or 88.

c. If “n” represents the level number of identifier-2 (and identifier-1), then no other data items with level

number “n” may be defined between identifier-1 and identifier-2.

d. The total allocated size of identifier-1 must be the same as the total allocated size of identifier-2.

e. No OCCURS clause may be defined on identifier-2. There may – however – be items defined with OCCURS clauses subordinate to identifier-2.

f. No VALUE clause may be defined on identifier-2. No data items subordinate to identifier-2 may have VALUE clauses, with the exception of level-88 condition names.

23. The following table summarizes the various possible USAGE specifications: Figure 5-10 - Summary of USAGE Specifications

Used USAGE

Storage

Allows

Allocated Space (Bytes)

Identical To

Depends on number of “9”s in PICTURE

Most-compatible If PICTURE Yes

COMPUTATIONAL,

and the ”binary-size” setting of the

– see # 24 contains

COMPUTATIONAL-4

configuration file (section 7.1.8 ) used to

“S”

compile the program

BINARY-CHAR or

One byte

Native – see # 24 Yes

No

BINARY-CHAR SIGNED BINARY-CHAR UNSIGNED

One byte

Native – see # 24 No – see

No

BINARY-C-LONG or

Allocates the same amount of storage as

Native – see # 24 Yes

No

BINARY-C-LONG SIGNED

does the C language “long” data type on that computer; typically this is 32 bits but it could be 64 bits

BINARY-C-LONG UNSIGNED

Allocates the same amount of storage as

Native – see # 24 No – see

No

does the C language “long” data type on

that computer; typically this is 32 bits but it could be 64 bits

BINARY-DOUBLE or

Allocates a “traditional” double-word of

Native – see # 24 Yes

No

BINARY-DOUBLE SIGNED

storage (64 bits)

BINARY-DOUBLE UNSIGNED

Allocates a “traditional” double-word of

Native – see # 24 No – see

No

storage (64 bits)

BINARY-LONG or

SIGNED-LONG, BINARY-LONG SIGNED

Allocates a word of storage (32 bits)

Native – see # 24 Yes

No

SIGNED-INT BINARY-LONG UNSIGNED

Allocates a word of storage (32 bits)

Native – see # 24 No – see

No

UNSIGNED-LONG, # 25 UNSIGNED-INT

BINARY-SHORT or

SIGNED-SHORT BINARY-SHORT SIGNED

Allocates a half-word of storage (16 bits)

Native – see # 24 Yes

No

BINARY-SHORT UNSIGNED

Allocates a half-word of storage (16 bits)

Native – see # 24 No – see

Depends on number of “9”s in PICTURE

Most-compatible If PICTURE Yes

BINARY, COMPUTATIONAL-4

and the ”binary-size” setting of the

– see # 24 contains

configuration file (section 7.1.8) used to

“S”

compile the program

COMPUTATIONAL-1

Allocates a word of storage (32 bits)

Allocates a double-word of storage (64

Double-precision Yes

Allocates 4 bits per “9” in the PICTURE

Packed decimal – If PICTURE No

PACKED-DECIMAL

plus a (trailing) 4-byte field for the sign,

see # 26 contains

rounded up to the nearest byte,

“S”

SYNCHRONIZED RIGHT (see # 27 )

COMPUTATIONAL-4

Depends on number of “9”s in PICTURE

Most-compatible If PICTURE Yes

BINARY, COMPUTATIONAL

and the ”binary-size” setting of the

– see # 24 contains

configuration file (section 7.1.8) used to

“S”

compile the program

COMPUTATIONAL-5

Depends on number of “9”s in PICTURE

If PICTURE Yes

and the ”binary-size” setting of the

contains

configuration file (section 7.1.8 ) used to

“S”

compile the program

Allocated Space (Bytes)

Identical To

Allocates bytes based upon the number

Most-compatible If PICTURE Yes

of “9”s in the PICTURE according to the

– see # 24 contains

”binary-size” setting of “1—8” in the

“S”

configuration file used to compile the program. See section 7.1.8 for an illustration of how a value of “1—8” for “binary-size” would work.

DISPLAY

Depends on PICTURE – One character 13 Characters

If PICTURE Yes

per X, A, 9, period, $, Z, 0, *, S (if

contains

SEPARATE CHARACTER specified), +, - or

“S”

B symbol in PICTURE; Add 2 more bytes if DB or CR symbol used

INDEX

Allocates a word of storage (32 bits)

Native – see # 24 No

No

NATIONAL

USAGE NATIONAL, while syntactically recognized, is not supported by OpenCOBOL

PACKED-DECIMAL

Allocates 4 bits per “9” in the PICTURE

Packed decimal – If PICTURE No

COMPUTATIONAL-3

plus a (trailing) 4-byte field for the sign,

see # 26 contains

rounded up to the nearest byte,

“S”

SYNCHRONIZED RIGHT (see # 27 )

POINTER

Allocates a word of storage (32 bits)

Native – see # 24 No

No

PROGRAM-POINTER

Allocates a word of storage (32 bits)

Native – see # 24 No

No

SIGNED-INT

Allocates a word of storage (32 bits)

Native – see # 24 Yes

No

BINARY-LONG-SIGNED, SIGNED-LONG

SIGNED-LONG

Allocates a word of storage (32 bits)

Native – see # 24 Yes

No

BINARY-LONG SIGNED, SIGNED-INT

SIGNED-SHORT

BINARY SHORT SIGNED UNSIGNED-INT

Allocates a half-word of storage (16 bits)

Native – see # 24 Yes

No

Allocates a word of storage (32 bits)

Native – see # 24 No – see

No

BINARY-LONG UNSIGNED, # 25 UNSIGNED-LONG

UNSIGNED-LONG

Allocates a word of storage (32 bits)

Native – see # 24 No – see

No

BINARY-LONG UNSIGNED, # 25 UNSIGNED-INT

UNSIGNED-SHORT

Allocates a half-word of storage (16 bits)

Native – see # 24 No – see

No

BINARY-SHORT UNSIGNED

24. Binary data can be stored in either a “Big-Endian” or “Little-Endian” form. Big-endian data allocation calls for the bytes that comprise a binary item to be allocated such that the least-

significant byte is the right-most byte. For example, a four-byte binary item having a value of decimal 20 would

be big-endian allocated as 00000014 (shown in hexadecimal notation). Little-endian data allocation calls for the bytes that comprise a binary item to be allocated such that the least-

significant byte is the left-most byte. For example, a four-byte binary item having a value of decimal 20 would be little-endian allocated as 14000000 (shown in hexadecimal notation).

A ll CPUs are capable of “understanding” big-endian format, which makes it the “most-compatible” form of binary storage across computer systems.

Some CPUs – such as the Intel/AMD i386/x64 architecture processors such as those used in most Windows PCs – prefer to process binary data stored in a little-endian format. Since that format is more efficient on those systems, it is referred to as the “native” binary format.

13 In t his context, one character is the same as one byte, unless you’ve built yourself an OpenCOBOL system that uses Unicode (unlikely), in which case 1 character = two bytes.

On a system supporting only one format of binary storage (generally, that would be big- endian), the terms “most- efficient” format and “native format” are synonymous.

25. Binary data items that have the UNSIGNED attribute explicitly coded, or that do not have an “S” symbol in their PICTURE clause cannot preserve negative values that may be stored into them. Attempts to store a negative value into such a field will actually result in the binary representation of the negative number actually being interpreted as if it were a positive number. For example, on a computer running an Intel or AMD processor, the

value of -3 expressed as a binary value would be 11111101 2 . If that value is moved into a USAGE BINARY-CHAR

UNSIGNED field, it would actually be interpreted as 011111101 2 , or 253.

26. Packed-decimal (i.e. USAGE COMP-3 or USAGE PACKED-DECIMAL) data is stored as a series of bytes such that each byte contains two 4- bit fields with each field representing a “9” in the PICTURE and storing a single decimal digit. The last byte will always contain a single 4- bit digit (corresponding to a “9” and a 4-bit sign indicator (always present, even if no “S” symbol is used). The first byte may contain an unused left-most 4-bit field, depending on how many “9” symbols were used in the PICTURE. The sign indicator will have a value of a hexadecimal A thru F, with values of A, C, E and F indicating a positive sign and B or D representing a negative value. Therefore, a PIC S9(3) COMP-3 packed-decimal field with a value of -15 would be stored internally as a hexadecimal 015D (or perhaps a 015B). If you attempt to store a negative number into a packed d ecimal field that has no “S” in its PICTURE, the absolute value of the negative number will actually be stored.

27. The SYNCHRONIZED clause (which may be abbreviated as SYNC) optimizes the storage of binary numeric items to store them in such a manner as to make it as fast as possible for the CPU to fetch them. This synchronization is performed as follows:

a. If the binary item occupies one byte of storage, no synchronization is performed.

b. If the binary item occupies two bytes of storage, the binary item is allocated at the next half-word boundary.

c. If the binary item occupies four bytes of storage, the binary item is allocated at the next word boundary.

d. If the binary item occupies four bytes of storage, the binary item is allocated at the next word boundary. Here’s an example of a group item’s storage allocation with and without using SYNCHRONIZED: Figure 5-11 - Effect of the SYNCHRONIZED Clause

01 Group-Item-1.

01 Group-Item-2.

05 A PIC X(1). 05 A PIC X(1). 05 B USAGE BINARY-SHORT.

05 B SYNC USAGE BINARY-SHORT. 05 C PIC X(2).

05 C PIC X(2). 05 D USAGE BINARY-LONG.

05 D SYNC USAGE BINARY-LONG. 05 E PIC X(3).

05 E PIC X(3). 05 F USAGE BINARY-DOUBLE.

05 F SYNC USAGE BINARY-DOUBLE.

½ Word Word Word Word Word Word Word Word Word Word Word Word Word

Group-Item-1 A B C D E F Group-Item-2 A B C D E F

The grey blocks represent the unused “slack” bytes that are allocated in the Group-Item-2 structure because of the SYNC clauses.

The LEFT and RIGHT options to the SYNCHRONIZED clause are recognized for syntactical compatibility with other COBOL implementations, but are otherwise non-functional.

28. Initializing a table is one of the trickier aspects of COBOL data definition. There are basically three standard techniques and a fourth that people familiar with other COBOL implementations but new to OpenCOBOL may find interesting . So, here are the three “standard” approaches:

a. Don’t bother worrying about it at compile-time. Use the INITIALIZE verb to initialize all data item occurrences in a table (at run-time) to their data-type-specific default values (numerics: 0, alphabetic and alphanumerics: SPACES).

b. Initialize small tables at compile time by including a VALUE clause on the group item that serves as a “parent” to the table, as follows:

05 SHIRT-SIZES VALUE “S 14M 15L 16XL17”. 10 SHIRT-SIZE-TBL OCCURS 4 TIMES. 15 SST-SIZE PIC X(2). 15 SST-NECK PIC 9(2).

c. Initialize tables of almost any size at compilation time by utilizing the REDEFINES clause: 05 SHIRT-SIZE-VALUES.

10 PIC X(4)

VALUE “S 14”.

10 PIC X(4)

VALUE “M 15”.

10 PIC X(4)

VALUE “L 16”.

10 PIC X(4)

VALUE “XL17”.

05 SHIRT-SIZES REDEFINES SHIRT-SIZE-VALUES. 10 SHIRT-SIZE-TBL OCCURS 4 TIMES. 15 SST-SIZE PIC X(2). 15 SST-NECK PIC 9(2).

Admittedly, the table shown in #28c is much more verbose than #28b. What is good about #28c, however, is that you can have as many FILLER/VALUE items as you need for a larger table (and those values can be as long as necessary!

Many COBOL compilers do not allow the use of VALUE and OCCURS on the same data item; additionally, they don’t allow a VALUE clause on a data item subordinate to an OCCURS. OpenCOBOL, however, has neither of these restrictions! Observe the following example, which illustrates the fourth manner in which tables may be initialized in OpenCOBOL:

05 X OCCURS 6 TIMES.

10 A PIC X(1) VALUE „?‟. 10 B PIC X (1) VALUE „%‟. 10 N PIC 9(2) VALUE 10.

In this example, all six “A” items will be initialized to “?”, all six “B” items will be initialized to “%” and all six “N” items will be initialized to 10. It’s not clear exactly how many times this sort of initialization will be useful, but it’s there if you need it.