There is subroutine like
subroutine A(x, N1, N2, Y)
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?
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.
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.
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.
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.
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
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.
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