VOLATILE clause

The VOLATILE clause indicates that a data item's value can be modified or referenced in ways that the compiler cannot detect, such as by a Language Environment® (LE) condition handler routine or by some other asynchronous process or thread. Thus, optimization is restricted for the data item.

Format

Read syntax diagramSkip visual syntax diagramVOLATILE
In particular, the compiler will enforce the following restrictions:
  • A volatile data item is loaded from memory each time it is referenced and stored to memory each time it is modified.
  • Loads and stores to the data item are never reordered or eliminated.
  • Storage is always allocated for the data item and initialized where necessary, even when no references to the data item are in the compilation unit.
    Note: The STGOPT option is ignored for data items that have the VOLATILE clause.

The VOLATILE clause can be specified on data items that are defined in the FILE SECTION, WORKING-STORAGE SECTION, LOCAL-STORAGE SECTION, and LINKAGE SECTION. This clause can be specified together with any other clauses. For example, VOLATILE can be specified on tables, group data items, elementary data items, record descriptions and variably located data items.

There are additional considerations for groups:
  • When a group item is explicitly defined with the VOLATILE clause, all items subordinate to the group item are treated as volatile by the compiler.
  • When a group item has one or more subordinate items that are explicitly defined with the VOLATILE clause, the group item is treated as volatile by the compiler.

The VOLATILE clause cannot be specified on level-66 or level-88 data items.

It is not possible to indicate that all memory associated with a class instance is volatile. However, individual members of a class can be defined with the VOLATILE clause.

Example of using VOLATILE with groups:

Consider the following group definition:
01 DATA-COLLECTION.                    
   03 DATA-ITEMS-A VOLATILE.           
      05 DATA-A1 PIC S9(9) BINARY.     
      05 DATA-A2 PIC S9(9) BINARY.     
   03 DATA-ITEMS-B.                    
      05 DATA-B1 PIC S9(9).
      05 DATA-B2 PIC S9(9) VOLATILE.   
   03 DATA-ITEMS-C. 
      05 DATA-C1 PIC S9(9). 
      05 DATA-C2 PIC S9(9).
In this example:
  • DATA-ITEMS-A and DATA-B2 are considered volatile because they are defined with the VOLATILE clause.
  • DATA-A1 and DATA-A2 are treated as volatile because they are both subordinate to a group item (DATA-ITEMS-A) that has the VOLATILE clause.
  • DATA-COLLECTION and DATA-ITEMS-B are treated as volatile because they are group items that have subordinates that are defined with the VOLATILE clause. For example:
    MOVE DATA-ITEMS-B TO DATA-ITEMS-C.
    In this case, by treating DATA-ITEMS-B as volatile, the compiler ensures that the latest value of its subordinate member DATA-B2 is used in the memory copy operation.

In the following LE condition handler scenario, it is necessary to specify the "STEP" data item with the VOLATILE clause to achieve correct results. In particular, if the VOLATILE clause is not used, the compiler might assume that "STEP" is never referenced between the assignment of "2" to "STEP" and the assignment of "3" to "STEP" and might therefore decide to eliminate the first assignment during optimization. Unfortunately, this could result in a problem because if a divide-by-zero condition occurs during execution of the subsequent line of code, the condition handler will execute and reference the external variable "STEP", which might have the incorrect value.

Main program:
IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 USER-HANDLER PROCEDURE-POINTER.
77 TOKEN   PIC S9(9) COMP.
01 QTY     PIC 9(8)  BINARY.
01 DIVISOR PIC 9(8)  BINARY VALUE 0.
01 ANSWER  PIC 9(8)  BINARY.
01 STEP    PIC 9(8)  BINARY VALUE 0 EXTERNAL VOLATILE.
:
SET USER-HANDLER TO ENTRY 'HANDLER'
CALL 'CEEHDLR' USING USER-HANDLER, TOKEN, NULL
COMPUTE STEP = 2                  *> Compiler thinks this store has no purpose and may remove it
COMPUTE ANSWER = NUMBER / DIVISOR *> Divide-by-zero exception occurs here, handler is invoked,
                                  *> and reference to 'STEP' is made but hidden from compiler
DISPLAY 'ANSWER = ' ANSWER
COMPUTE STEP = 3
DISPLAY 'STEP = ' STEP
COMPUTE ANSWER = QTY + 2
:
Condition handler program:
IDENTIFICATION DIVISION.
PROGRAM-ID. HANDLER.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 STEP PIC 9(8) BINARY EXTERNAL.
PROCEDURE DIVISION.
:
DISPLAY 'ERROR: A PROBLEM WAS ENCOUNTERED IN STEP ' STEP.