Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29427 Discussions

Documentation error for SAVE behavior

OP1
New Contributor III
232 Views

I believe there is an error in the SAVE documentation (link). It says:

The following variables are saved by default: ... Initialized (see above Note) variables

And the "above Note" defines Initialized variables as:

In the following lists, "initialized" means that the variable has been given an initial value in a DATA statement, it has been initialized in a type declaration statement, it is of a derived type that is default initialized, or it has a component that is default initialized.

The bold emphasis is mine, and I do not believe it is correct. The output of the code below shows that the procedure variable Y, which is an object of derived type T, where T has a component I that is default initialized, does NOT have an implied SAVE attribute.

This contrasts with the procedure variable X (of the same type), which is explicitly default initialized in its declaration statement, and which thus DOES have the implied attribute.

This behavior difference is highlighted by the code output.

PROGRAM P
IMPLICIT NONE
TYPE :: T
   INTEGER :: I = 100
END TYPE T
CALL S
CALL S
CONTAINS
    SUBROUTINE S
    IMPLICIT NONE
    TYPE(T) :: X = T(8), Y
    X%I = X%I + 1
    Y%I = Y%I + 1
    WRITE(*, *) X%I, Y%I
    END SUBROUTINE S
END PROGRAM P

 

 9 101
 10 101
Press any key to continue . . .

 

0 Kudos
2 Replies
JohnNichols
Valued Contributor III
191 Views

This works using the save, as is good programming practice, expecting default init in Fortran is always chancy.   You are of course correct. 

But Fortran is old and so some features are challenging to say the least.  As I tell my daughter, some people drive stick and some automatic and some program Fortran and most Python.  She looks at me and says, stick is  hard Dad. 

PROGRAM P
IMPLICIT NONE
TYPE :: T
   INTEGER :: I != 100
END TYPE T
CALL S
CALL S
CALL S
CALL S
CALL S
CALL S
CONTAINS
    SUBROUTINE S
    IMPLICIT NONE
    TYPE(T),  SAVE :: X = T(8), Y
    X%I = X%I + 1
    Y%I = Y%I + 1
    WRITE(*, *) X%I, Y%I
    END SUBROUTINE S
END PROGRAM P

 

0 Kudos
Steve_Lionel
Honored Contributor III
181 Views

You are correct. 7.5.4.6p6 says, "Unlike explicit initialization, default initialization does not imply that the object has the SAVE attribute."

There's an interesting effect of default initialization that can catch experienced Fortran programmers by surprise. It's tucked into the list of "Events that cause variables to become defined":

(23) Invocation of a procedure that contains an unsaved nonpointer nonallocatable local variable causes all nonpointer default-initialized subcomponents of the object to become defined.
(24) Invocation of a procedure that has a nonpointer nonallocatable INTENT (OUT) dummy argument causes all nonpointer default-initialized subcomponents of the dummy argument to become defined.

It makes sense when you think about it, but it feels weird in Fortran to have initializations recur for each invocation of a procedure.

0 Kudos
Reply