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

Unusual changing of initialized variable

Mike_Z_
Novice
436 Views

There is subroutine like

subroutine A(x, N1, N2, Y)
implicit none
integer N1, N2
real*8 X, Y(N1:N2), P/0.0d0/, Z
 
write(7, *) P
...
P = Z
...
end subroutine a

At first call of A variable P prints right value 0.0d0, but at second call it prints non zero value. How it could be possible?

 

0 Kudos
9 Replies
NotThatItMatters
Beginner
436 Views

Using the initialization statement with P gives P the SAVE attribute in the SUBROUTINE.  The initializer then only has precedence on the initial call.  Thereafter, the value of P is the previous value at SUBROUTINE completion.

0 Kudos
Mike_Z_
Novice
436 Views

Thanks. So, it is the same behavior as DATA statemnt.

0 Kudos
NotThatItMatters
Beginner
436 Views

Yes, precisely.  As a colleague of mine commented, this is because the Fortran SUBROUTINE is by nature STATIC.  Mind you, he is doing his coding in C#, so he stays clear of my world.

0 Kudos
Steven_L_Intel1
Employee
436 Views

No, the Fortran SUBROUTINE is not "by nature STATIC". The only thing that makes the variable static (SAVE) in this case is the initialization. It was common in the past for Fortran compilers to make everything static, or some things static, but the language doesn't specify that and modern compilers tend not to do that.

0 Kudos
NotThatItMatters
Beginner
436 Views

Okay, I stand corrected.  The "static" variables are explicitly declared variables.  In C, this is not the case.

0 Kudos
Steven_L_Intel1
Employee
436 Views

You mean local variables with the "static" attribute in C. In Fortran that is spelled SAVE, but the concept is the same. If instead you're referring to initialization in the declaration, then C and Fortran do work differently here.

0 Kudos
William_S_2
Beginner
436 Views

I have the same Fortran problem. You described it well. A variable is set in a subroutine and if immediately printed, it is correct. But if you leave the subroutine and then return, it has lost its value. In my case, an integer(4) variable reverts to the equivalent of all binary 1's in the four-byte memory (-858993460) that memory location

0 Kudos
Arjen_Markus
Honored Contributor I
436 Views

William, variables in subprograms only retain their values if they have the SAVE attribute. You cannot expect anything reliable about the value of local variables without that attribute. So, if you want that variable to retain its value, declare it with SAVE:

integer, save :: my_pet_var

There are other possibilities, see above, but I find it best to use SAVE explicitly.

0 Kudos
jimdempseyatthecove
Honored Contributor III
436 Views

And... if you want the same initialization on each call to the subroutine specifically set the value as a separate statement as opposed to in the declaration with initialization.

!DIR$ IF DEFINED(NotThisWay)
real*8 X, Y(N1:N2), P/0.0d0/, Z ! once only initialization of P
!DIR$ ELSE
real*8 X, Y(N1:N2), P, Z
...
! variable initialization
P = 0.0d0 ! each call initialization of P
!DIR$ ENDIF

Jim Dempsey

0 Kudos
Reply