Intel® Fortran Compiler Classic and Intel® Fortran Compiler Developer Guide and Reference

ID 767251
Date 3/22/2024
Public
Document Table of Contents

MOVE_ALLOC

Intrinsic Subroutine (Generic): Moves an allocation from one allocatable object to another. Intrinsic subroutines cannot be passed as actual arguments.

CALL MOVE_ALLOC (from,to [, stat, errmsg])

from

(Input; output) Can be of any type, type parameters, corank, and rank; it must be allocatable.

to

(Output) Must be type compatible with from and have the same rank and corank; it must be allocatable. It must be polymorphic if from is polymorphic. Each nondeferred type parameter of the declared type of to must have the same value as the corresponding type parameter of the declared type of from. For more information about type compatibility, see the description in CLASS.

stat

(Output, optional) Must be a non-coindexed integer scalar with a decimal exponent range of at least 4 (KIND=2) or greater.

errmsg

(Input; output; optional) Must be a non-coindexed default character variable.

When the execution of MOVE_ALLOC is successful, or if STAT is assigned the value STAT_FAILED_IMAGE, the following occurs:

  • If to is currently allocated, it is deallocated.

  • If from is allocated, to becomes allocated with the same type, type parameters, array bounds, and values as from.

  • from is deallocated.

If to has the TARGET attribute, any pointer associated with from at the time of the call to MOVE_ALLOC becomes correspondingly associated with to. If to does not have the TARGET attribute, the pointer association status of any pointer associated with from on entry becomes undefined.

During execution of MOVE_ALLOC, the internal descriptor contents are copied from from to to, so that the storage pointed to by to is the storage that from used to point to.

Typically, MOVE_ALLOC is used to provide an efficient way to reallocate a variable to a larger size without copying the data twice.

A reference to MOVE_ALLOC that has a coarray from argument has an implicit synchronization of all active images of the current team. No image proceeds until all active images of the current team have completed execution of the reference. If the current team contains any images that have stopped or failed, an error condition occurs.

If the procedure reference is successful, stat becomes defined with the value zero.

If an error condition occurs and stat is not specified, error termination is initiated. If stat is present and the current team contains an image that has stopped, stat becomes defined with the value STAT_STOPPED_IMAGE from the intrinsic module ISO_FORTRAN_ENV. Otherwise, if stat is present, the current team contains a failed image, and no other error condition occurs, stat becomes defined with the value STAT_FAILED_IMAGE from the intrinsic module ISO_FORTRAN_ENV. Otherwise, stat becomes defined with a positive integer value different from STAT_STOPPED_IMAGE and STAT_FAILED_IMAGE.

The definition status of errmsg, if present, remains unchanged if the execution of the reference is successful. If errmsg is present and an error condition occurs, errmsg becomes defined with an explanatory message describing the error.

Example

The following shows an example of how to increase the allocated size of X and keep the old values with only one copy of the old values. Using only assignment, a temporary variable named Y will be allocated and X assigned to Y. Then X will be deallocated and reallocated to be twice the size; then Y will be assigned to the first half of X. Finally, the temporary Y is deallocated.


    ! This program uses MOVE_ALLOC to make an allocated array X bigger and
    ! keep the old values of X in the variable X. Only one copy of the old values
    ! of X is needed.
        integer :: I, N = 2
        real, allocatable :: X(:), Y(:)
        allocate (X(N), Y(2*N))         ! Y is twice as big as X
        X = (/(I,I=1,N)/)       ! put "old values" into X
        Y = -1                  ! put different "old values" into Y
        print *, ' allocated of X is ', allocated (X)
        print *, ' allocated of Y is ', allocated (Y)
        print *, ' old X is ', X
        print *, ' old Y is ', Y
        Y (1:N) = X             ! copy all of X into the first half of Y
                                ! this is the only copying of values required
        print *, ' new Y is ', Y
        call move_alloc (Y, X)  ! X is now twice as big as it was, Y is
                                ! deallocated, the values were not copied from Y to X
        print *, ' allocated of X is ', allocated (X)
        print *, ' allocated of Y is ', allocated (Y)
        print *, ' new X is ', X
        end

The following shows the output for the above example:

    allocated of X is  T
    allocated of Y is  T
    old X is    1.000000       2.000000
    old Y is   -1.000000      -1.000000      -1.000000      -1.000000
    new Y is    1.000000       2.000000      -1.000000      -1.000000
    allocated of X is  T
    allocated of Y is  F
    new X is    1.000000       2.000000      -1.000000      -1.000000