Previous | Contents | Index |
The VOLATILE attribute specifies that the value of an object is entirely unpredictable, based on information local to the current program unit. It prevents objects from being optimized during compilation.
The VOLATILE attribute can be specified in a type declaration statement or a VOLATILE statement, and takes one of the following forms:
Type Declaration Statement:
|
Statement:
|
type
Is a data type specifier.att-ls
Is an optional list of attribute specifiers.object
Is the name of an object, or the name of a common block enclosed in slashes.
A variable or COMMON block must be declared VOLATILE if it can be read or written in a way that is not visible to the compiler. For example:
If an array is declared VOLATILE, each element in the array becomes volatile. If a common block is declared VOLATILE, each variable in the common block becomes volatile.
If an object of derived type is declared VOLATILE, its components become volatile.
If a pointer is declared VOLATILE, the pointer itself becomes volatile.
A VOLATILE statement cannot specify the following:
The following example shows a type declaration statement specifying the VOLATILE attribute:
INTEGER, VOLATILE :: D, E |
The following example shows a VOLATILE statement:
PROGRAM TEST LOGICAL(1) IPI(4) INTEGER(4) A, B, C, D, E, ILOOK INTEGER(4) P1, P2, P3, P4 COMMON /BLK1/A, B, C VOLATILE /BLK1/, D, E EQUIVALENCE(ILOOK, IPI) EQUIVALENCE(A, P1) EQUIVALENCE(P1, P4) |
The named common block, BLK1, and the variables D and E are volatile. Variables P1 and P4 become volatile because of the direct equivalence of P1 and the indirect equivalence of P4.
This chapter describes:
Data objects can be static or dynamic. If a data object is static, a fixed amount of memory storage is created for it at compile time and is not freed until the program exits. If a data object is dynamic, memory storage for the object can be created (allocated), altered, or freed (deallocated) as a program executes.
In Fortran 95/90, pointers, allocatable arrays, and automatic arrays are dynamic data objects.
No storage space is created for a pointer until it is allocated with an ALLOCATE statement or until it is assigned to a allocated target. A pointer can be dynamically disassociated from a target by using a NULLIFY statement.
An ALLOCATE statement can also be used to create storage for an allocatable array. A DEALLOCATE statement is used to free the storage space reserved in a previous ALLOCATE statement.
Automatic arrays differ from allocatable arrays in that they are automatically allocated and deallocated whenever you enter or leave a procedure, respectively.
The ALLOCATE statement dynamically creates storage for allocatable arrays and pointer targets. The storage space allocated is uninitialized.
The ALLOCATE statement takes the following form:
|
object
Is the object to be allocated. It is a variable name or structure component, and must be a pointer or allocatable array. The object can be of type character with zero length.s-spec
Is a shape specification in the form [lower-bound:]upper-bound. Each bound must be a scalar integer expression. The number of shape specifications must be the same as the rank of the object.sv
Is a scalar integer variable in which the status of the allocation is stored.
A bound in s-spec must not be an expression containing an array inquiry function whose argument is any allocatable object in the same ALLOCATE statement; for example, the following is not permitted:
INTEGER ERR INTEGER, ALLOCATABLE :: A(:), B(:) ... ALLOCATE(A(10:25), B(SIZE(A)), STAT=ERR) ! A is invalid as an argument ! to function SIZE |
If a STAT variable is specified, it must not be allocated in the ALLOCATE statement in which it appears. If the allocation is successful, the variable is set to zero. If the allocation is not successful, an error condition occurs, and the variable is set to a positive integer value (representing the run-time error). If no STAT variable is specified and an error condition occurs, program execution terminates.
The following is an example of the ALLOCATE statement:
INTEGER J, N, ALLOC_ERR REAL, ALLOCATABLE :: A(:), B(:,:) ... ALLOCATE(A(0:80), B(-3:J+1, N), STAT = ALLOC_ERR) |
The bounds (and shape) of an allocatable array are determined when it is allocated. Subsequent redefinition or undefinition of any entities in the bound expressions does not affect the array specification.
If the lower bound is greater than the upper bound, that dimension has an extent of zero, and the array has a size of zero. If the lower bound is omitted, it is assumed to be 1.
When an array is allocated, it is definable. If you try to allocate a currently allocated allocatable array, an error occurs.
The intrinsic function ALLOCATED can be used to determine whether an allocatable array is currently allocated; for example:
REAL, ALLOCATABLE :: E(:,:) ... IF (.NOT. ALLOCATED(E)) ALLOCATE(E(2:4,7)) |
During program execution, the allocation status of an allocatable array is one of the following:
If an allocatable array has the SAVE attribute, it has an initial status of "not currently allocated." If the array is then allocated, its status changes to "currently allocated." It keeps that status until the array is deallocated.
If an allocatable array does not have the SAVE attribute, it has the status of "not currently allocated" at the beginning of each invocation of the procedure. If the array's status changes to "currently allocated", it is deallocated if the procedure is terminated by execution of a RETURN or END statement.
Example 6-1 shows a program that performs virtual memory allocation. This program uses Fortran 95/90 standard-conforming statements instead of calling an operating system memory allocation routine.
Example 6-1 Allocating Virtual Memory |
---|
! Program accepts an integer and displays square root values INTEGER(4) :: N READ (5,*) N ! Reads an integer value CALL MAT(N) END ! Subroutine MAT uses the typed integer value to display the square ! root values of numbers from 1 to N (the number read) SUBROUTINE MAT(N) REAL(4), ALLOCATABLE :: SQR(:) ! Declares SQR as a one-dimensional ! allocatable array ALLOCATE (SQR(N)) ! Allocates array SQR DO J=1,N SQR(J) = SQRT(FLOATJ(J)) ! FLOATJ converts integer to REAL ENDDO WRITE (6,*) SQR ! Displays calculated values DEALLOCATE (SQR) ! Deallocates array SQR END SUBROUTINE MAT |
On the ALLOCATED intrinsic function, see Section 9.4.10.
6.2.2 Allocation of Pointer Targets
When a pointer is allocated, the pointer is associated with a target and can be used to reference or define the target. (The target can be an array or a scalar, depending on how the pointer was declared.)
Other pointers can become associated with the pointer target (or part of the pointer target) by pointer assignment.
In contrast to allocatable arrays, a pointer can be allocated a new target even if it is currently associated with a target. The previous association is broken and the pointer is then associated with the new target.
If the previous target was created by allocation, it becomes inaccessible unless it can still be referred to by other pointers that are currently associated with it.
The intrinsic function ASSOCIATED can be used to determine whether a pointer is currently associated with a target. (The association status of the pointer must be defined.) For example:
REAL, TARGET :: TAR(0:50) REAL, POINTER :: PTR(:) PTR => TAR ... IF (ASSOCIATED(PTR,TAR))... |
The DEALLOCATE statement frees the storage allocated for allocatable arrays and pointer targets (and causes the pointers to become disassociated). It takes the following form:
|
object
Is a structure component or the name of a variable, and must be a pointer or allocatable array.sv
Is a scalar integer variable in which the status of the deallocation is stored.
If a STAT variable is specified, it must not be deallocated in the DEALLOCATE statement in which it appears. If the deallocation is successful, the variable is set to zero. If the deallocation is not successful, an error condition occurs, and the variable is set to a positive integer value (representing the run-time error). If no STAT variable is specified and an error condition occurs, program execution terminates.
It is recommended that all explicitly allocated storage be explicitly deallocated when it is no longer needed.
The following example shows deallocation of an allocatable array:
INTEGER ALLOC_ERR REAL, ALLOCATABLE :: A(:), B(:,:) ... ALLOCATE (A(10), B(-2:8,1:5)) ... DEALLOCATE(A, B, STAT = ALLOC_ERR) |
On run-time error messages, see the HP Fortran for OpenVMS User Manual or online
documentation.
6.3.1 Deallocation of Allocatable Arrays
If the DEALLOCATE statement specifies an array that is not currently allocated, an error occurs.
If an allocatable array with the TARGET attribute is deallocated, the association status of any pointer associated with it becomes undefined.
If a RETURN or END statement terminates a procedure, an allocatable array has one of the following allocation statuses:
The intrinsic function ALLOCATED can be used to determine whether an allocatable array is currently allocated; for example:
SUBROUTINE TEST REAL, ALLOCATABLE, SAVE :: F(:,:) REAL, ALLOCATABLE :: E(:,:,:) ... IF (.NOT. ALLOCATED(E)) ALLOCATE(E(2:4,7,14)) END SUBROUTINE TEST |
Note that when subroutine TEST is exited, the allocation status of F is maintained because F has the SAVE attribute. Since E does not have the SAVE attribute, it is deallocated. On the next invocation of TEST, E will have the status of "not currently allocated."
A pointer must not be deallocated unless it has a defined association status. If the DEALLOCATE statement specifies a pointer that has undefined association status, or a pointer whose target was not created by allocation, an error occurs.
A pointer must not be deallocated if it is associated with an allocatable array, or it is associated with a portion of an object (such as an array element or an array section).
If a pointer is deallocated, the association status of any other pointer associated with the target (or portion of the target) becomes undefined.
Execution of a RETURN or END statement in a subprogram causes the pointer association status of any pointer declared (or accessed) in the procedure to become undefined, unless any of the following applies to the pointer:
If the association status of a pointer becomes undefined, it cannot subsequently be referenced or defined.
The following example shows deallocation of a pointer:
INTEGER ERR REAL, POINTER :: PTR_A(:) ... ALLOCATE (PTR_A(10), STAT=ERR) ... DEALLOCATE(PTR_A) |
The NULLIFY statement disassociates a pointer from its target. It takes the following form:
|
pointer-object
Is a structure component or the name of a variable; it must be a pointer (have the POINTER attribute).
The initial association status of a pointer is undefined. You can use NULLIFY to initialize an undefined pointer, giving it disassociated status. Then the pointer can be tested using the intrinsic function ASSOCIATED.
The following is an example of the NULLIFY statement:
REAL, TARGET :: TAR(0:50) REAL, POINTER :: PTR_A(:), PTR_B(:) PTR_A => TAR PTR_B => TAR ... NULLIFY(PTR_A) |
After these statements are executed, PTR_A will have disassociated status, while PTR_B will continue to be associated with variable TAR.
Previous | Next | Contents | Index |