Showing posts with label COBOL Data Division. Show all posts
Showing posts with label COBOL Data Division. Show all posts

Thursday, 14 August 2014

COBOL REDEFINES Clause: Rules and Practical Examples

05 DATE-FIELDS REDEFINES DATE-TEXT lets a COBOL program view the same eight bytes as one text value or as year, month, and day fields. No MOVE occurs when the alternate name is referenced. Both descriptions begin at the same storage address.

COBOL REDEFINES clause showing the same eight bytes as date text and separate year month day fields
REDEFINES supplies alternate descriptions of one storage area; writing through either description changes the same bytes.

What the COBOL REDEFINES clause does

The COBOL REDEFINES clause overlays one data description on another. It is useful when an input record has several formats, when a field needs both a group and elementary view, or when existing bytes must be split into named subfields without copying them.

REDEFINES changes the description, not the data. COBOL does not convert character digits into packed decimal, validate a date, or select the correct transaction format. The program must know which layout matches the bytes before using fields whose class or usage imposes numeric rules.

Storage rule: the original item and its alternate descriptions occupy overlapping character positions. Redefinitions and renamings do not add their sizes again when COBOL determines a record length.

Basic REDEFINES syntax

level-number data-name-1 REDEFINES data-name-2.
   subordinate-data-items

data-name-1 is the redefining subject. data-name-2 is the earlier item whose storage is being described again. The clause follows the redefining name and must be the first clause in that data description entry.

The two entries use the same level number within the same record area. The redefined name must already be defined. A lower level number cannot intervene in a way that ends the containing group. Use the COBOL Data Division guide for level numbers and record hierarchy.

Example 1: split an eight-byte date

01  WS-DATE-AREA.
    05  WS-DATE-TEXT         PIC X(8).
    05  WS-DATE-FIELDS REDEFINES WS-DATE-TEXT.
        10  WS-DATE-YEAR     PIC 9(4).
        10  WS-DATE-MONTH    PIC 9(2).
        10  WS-DATE-DAY      PIC 9(2).

    MOVE '20260908' TO WS-DATE-TEXT
    DISPLAY WS-DATE-YEAR
    DISPLAY WS-DATE-MONTH
    DISPLAY WS-DATE-DAY

The MOVE stores eight character bytes. The subordinate numeric-display fields occupy those same positions, so the displays produce 2026, 09, and 08. This works because every byte contains a valid display digit.

No automatic validation: if WS-DATE-TEXT contains 2026AB08, the month field is not valid numeric data. Test the source or use a date-validation routine before numeric processing.

Example 2: select a transaction layout

01  INPUT-RECORD.
    05  RECORD-TYPE          PIC X.
        88  SALES-RECORD     VALUE 'S'.
        88  RETURN-RECORD    VALUE 'R'.
    05  RECORD-DATA          PIC X(19).
    05  SALES-DATA REDEFINES RECORD-DATA.
        10  SALE-ITEM        PIC X(8).
        10  SALE-QUANTITY    PIC 9(5).
        10  SALE-AMOUNT      PIC 9(6).
    05  RETURN-DATA REDEFINES RECORD-DATA.
        10  RETURN-ITEM      PIC X(8).
        10  RETURN-CODE      PIC X(3).
        10  RETURN-AMOUNT    PIC 9(6).
        10  FILLER           PIC X(2).

EVALUATE TRUE
  WHEN SALES-RECORD
       PERFORM PROCESS-SALE
  WHEN RETURN-RECORD
       PERFORM PROCESS-RETURN
  WHEN OTHER
       PERFORM REJECT-RECORD
END-EVALUATE

The discriminator sits outside the overlaid 19-byte area. The program tests it before referencing numeric fields in SALES-DATA or RETURN-DATA. Multiple alternate descriptions name the original RECORD-DATA, which makes the common storage owner clear.

This pattern is common in copybooks for fixed-format files and messages. The file's actual record length must still match the FD and data-set attributes. See the COBOL fixed versus variable-length record guide.

Example 3: inspect packed-decimal bytes

01  AMOUNT-AREA.
    05  WS-AMOUNT            PIC S9(7)V99 COMP-3.
    05  WS-AMOUNT-BYTES REDEFINES WS-AMOUNT
                             PIC X(5).

A nine-digit signed packed-decimal item occupies five bytes. The alphanumeric overlay can be useful when moving the exact stored representation to a diagnostic field or examining it in a dump. It does not turn the packed value into readable decimal text.

Do not DISPLAY the byte overlay and expect 123.45. Use an edited numeric receiving field for presentation. The COBOL USAGE clause guide explains DISPLAY, COMP, COMP-3, and COMP-5 storage.

REDEFINES rules that matter in production

RulePractical effect
Subject and object use the same level.An 05-level item overlays another 05-level item, not one of its 10-level children.
The object is defined earlier.The compiler must already know the storage area being described again.
The object cannot contain OCCURS on its own entry.Do not name a table item itself as the REDEFINES object; restructure the surrounding group where allowed.
The subject and its subordinate items cannot contain VALUE clauses.Initialization belongs on the original definition or in executable logic.
Several alternates can overlay one original item.Name the original object in each REDEFINES clause.
EXTERNAL cannot be on the same entry as REDEFINES.External-record layouts have additional size and consistency rules.
GLOBAL belongs only to the redefining subject when coded there.The GLOBAL attribute does not automatically pass to the object.

Do the layouts need equal lengths?

Equal lengths make a record overlay easiest to review, but current Enterprise COBOL does not impose one simple equal-length rule on every case. IBM permits a non-level-01 redefining item to be larger than the item it overlays. This extension does not increase the size of the original item.

Level-01, external-record, file-description, OCCURS, and compiler-compatibility cases have additional restrictions. Treat unequal overlays as a design requiring compiler-listing review and boundary tests. RULES(NOLAXREDEF) can request warnings for certain smaller redefinitions.

Review with offsets: use the compiler data map to compare displacement and length for the original and every alternate. The code may compile while an intended child field still starts on the wrong byte.

REDEFINES versus RENAMES

REDEFINES supplies an alternate data description for the same starting storage area and can change the subordinate structure or data categories. RENAMES uses a level-66 entry to give another name to one item or a contiguous range of existing items.

Use REDEFINES for variant layouts. Use RENAMES when the requirement is another group name for already described positions. The COBOL RENAMES clause guide covers level 66 and THRU.

REDEFINES and variable records

Alternate 01-level records under an FD can describe different record formats. The maximum record size and file organization still come from the FD clauses, record descriptions, and data-set attributes. REDEFINES does not by itself make a QSAM or VSAM record variable length.

When a file truly contains variable-length records, use the applicable RECORD IS VARYING, multiple 01-level descriptions, or OCCURS DEPENDING ON design. Keep the maximum COBOL record length consistent with LRECL and the access method.

Common REDEFINES errors

  • Expecting the alternate item to receive a copied or converted value.
  • Placing the overlay at a different level from the original item.
  • Naming an OCCURS item directly as the object.
  • Coding VALUE on the redefining item or one of its children.
  • Using a numeric alternate before checking the record-type field.
  • Assuming an alphanumeric view of COMP-3 produces readable digits.
  • Changing a copybook overlay without comparing every consumer's offsets.
  • Using REDEFINES where a MOVE and validation would express the requirement more safely.

If the wrong overlay produces invalid packed or zoned data, a numeric instruction can fail with S0C7. Preserve the input record, identify the active layout, and inspect field offsets before changing the arithmetic statement.

Safe coding checklist

  • Keep a discriminator outside the overlaid data when records have variants.
  • Name the raw storage area and every business layout clearly.
  • Match total lengths unless a documented unequal-size design is intentional.
  • Confirm numeric bytes before arithmetic, comparison, or conversion.
  • Check the compiler map after changing a copybook.
  • Regression-test every record type, including rejected and truncated input.
  • Confirm FD length rules for file records.

The Working-Storage versus Local-Storage guide explains lifetime and initialization, while the COBOL TRUNC guide covers binary receiving fields.

Official IBM references

COBOL REDEFINES clause FAQ

Does COBOL REDEFINES allocate more storage?

No. The original item and the redefining item describe the same storage positions. COBOL does not copy or convert the bytes when another description is referenced.

Must the two REDEFINES items have the same level number?

The subject and object use the same level number and belong to the same record area. Level 66 and level 88 entries are not used as ordinary REDEFINES subjects or objects.

Can the item named after REDEFINES contain OCCURS?

No. IBM states that the data description entry for the redefined object cannot itself contain an OCCURS clause. A group layout can still contain subordinate table definitions where the applicable rules permit them.

Why can REDEFINES cause an S0C7 abend?

REDEFINES does not validate which layout matches the bytes. If character data is processed through a numeric or packed-decimal description, a numeric operation can raise a data exception such as S0C7.

Use REDEFINES only after the program has a reliable way to identify which description matches the bytes currently in the shared storage area.

Sunday, 22 September 2013

COBOL Working Storage vs Local Storage: Key Differences

COBOL Working Storage vs Local Storage comparison showing persistent values and fresh copy per call
Working Storage keeps state; Local Storage starts fresh for each call.

A COBOL subprogram can return cleanly on the first call and fail on the second because a counter, switch, or table entry kept its old value in WORKING-STORAGE. Move the same item to LOCAL-STORAGE, and COBOL allocates a fresh copy for each call. That is the practical difference developers need before debugging a strange rerun or CALL problem.

Short rule: Working Storage persists for the run unit unless the program is initialised again. Local Storage is allocated for each invocation and freed when the program returns.

Working Storage vs Local Storage Comparison

Question Working Storage Local Storage
Scope Visible to the program that defines it. Visible to the program or method invocation that defines it.
Initialisation VALUE clauses are applied when the run unit starts, or when the program is reinitialised after CANCEL or INITIAL. VALUE clauses are applied on each call or method invocation. Without VALUE, the initial content is undefined.
Persistence between CALL statements Usually keeps the last-used value between calls in the same run unit. Does not keep values after return. A new copy is allocated for the next invocation.
When to use Use for program-level state that must remain available across paragraphs or repeated calls. Use for temporary work fields that should start fresh for each call, especially in reusable subprograms.

What Working Storage Means in COBOL

WORKING-STORAGE SECTION is part of the COBOL Data Division. It defines fields that belong to the program and remain available while the program is active in the run unit. A batch driver that calls the same subprogram many times can therefore see old values if the subprogram keeps counters, switches, or save areas in Working Storage and does not reset them.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-CALL-COUNT        PIC 9(4) VALUE ZERO.
01 WS-LAST-CUSTOMER     PIC X(10).

PROCEDURE DIVISION.
    ADD 1 TO WS-CALL-COUNT
    DISPLAY 'CALL COUNT=' WS-CALL-COUNT
    GOBACK.

If this program is called three times in the same run unit, WS-CALL-COUNT can show 1, then 2, then 3. That is useful when the program intentionally tracks state. It is a bug when the field was meant to be temporary.

What Local Storage Means in COBOL

LOCAL-STORAGE SECTION defines fields that are allocated when the program or method is invoked and freed when it returns. This makes Local Storage a good fit for scratch variables in reusable routines, recursive-style logic, and programs that may run in multiple invocations.

DATA DIVISION.
LOCAL-STORAGE SECTION.
01 LS-ITEM-AMOUNT       PIC 9(5) VALUE ZERO.
01 LS-WORK-FLAG         PIC X    VALUE 'N'.

PROCEDURE DIVISION.
    MOVE 'Y' TO LS-WORK-FLAG
    GOBACK.

On the next call, LS-WORK-FLAG is allocated again and the VALUE clause is applied again. That behavior is often safer for work fields that should not remember a previous transaction, customer, or input record.

CALL Behavior That Causes Runtime Errors

The easiest trap is a subprogram called repeatedly from a driver. A field in Working Storage keeps its last value, so a flag that should start as N might still be Y. A table index might still point past the last loaded entry. A previous customer number might leak into the next calculation.

Use Working Storage when that persistence is intentional. Use Local Storage when each call should start with a clean set of work fields. If a program uses PROGRAM-ID. name IS INITIAL, or if the caller issues CANCEL before calling again, Working Storage can be reinitialised, but that is a program-control decision and should not be hidden inside a variable naming habit.

Threading Difference

In environments where the same program can run in multiple simultaneous invocations, Working Storage can be shared by those invocations, while Local Storage gives each invocation a separate copy. That difference matters in CICS and other multi-tasking designs. If a field belongs to one transaction, request, or invocation, Local Storage is usually the safer place.

Where This Fits in the Data Division

Both sections belong to the COBOL Data Division, along with File Section and Linkage Section. For a broader layout of the Data Division, see the COBOL Data Division guide. If your bug is about fields passed between a caller and subprogram, also review the COBOL CALL statement and parameter passing guide.

Common Mistakes

  • Putting a temporary transaction flag in Working Storage and forgetting to reset it before every call.
  • Assuming Local Storage keeps a value after GOBACK.
  • Using VALUE clauses as a substitute for explicit reset logic in a long-running program.
  • Treating CANCEL as harmless when the called program relies on Working Storage persistence.

Practical Rule

If the value must survive the next call, use Working Storage and reset it deliberately when needed. If the value belongs only to this invocation, use Local Storage so old data cannot sneak into the next run path.

New In-feed ads