Does Fortran preserve the value of internal variables through function and subroutine calls?

Viewed 7704

After much painful debugging, I believe I've found a unique property of Fortran that I'd like to verify here at stackoverflow.

What I've been noticing is that, at the very least, the value of internal logical variables are preserved across function or subroutine calls.

Here is some example code to illustrate my point:

PROGRAM function_variable_preserve
IMPLICIT NONE

CHARACTER(len=8) :: func_negative_or_not ! Declares function name
INTEGER :: input
CHARACTER(len=8) :: output

input = -9

output = func_negative_or_not(input)
WRITE(*,10) input, " is ", output
10 FORMAT("FUNCTION: ", I2, 2A)

CALL sub_negative_or_not(input, output)
WRITE(*,20) input, " is ", output
20 FORMAT("SUBROUTINE: ", I2, 2A)

WRITE(*,*) 'Expected negative.'


input = 7
output = func_negative_or_not(output)
WRITE(*,10) input, " is ", output

CALL sub_negative_or_not(input, output)
WRITE(*,20) input, " is ", output

WRITE(*,*) 'Expected positive.'

END PROGRAM function_variable_preserve

CHARACTER(len=*) FUNCTION func_negative_or_not(input)
IMPLICIT NONE

INTEGER, INTENT(IN) :: input
LOGICAL :: negative = .FALSE.

IF (input < 0) THEN
    negative = .TRUE.
END IF

IF (negative) THEN
    func_negative_or_not = 'negative'
ELSE 
    func_negative_or_not = 'positive'
END IF

END FUNCTION func_negative_or_not

SUBROUTINE sub_negative_or_not(input, output)
IMPLICIT NONE

INTEGER, INTENT(IN) :: input
CHARACTER(len=*), INTENT(OUT) :: output
LOGICAL :: negative = .FALSE.

IF (input < 0) THEN
    negative = .TRUE.
END IF

IF (negative) THEN
    output = 'negative'
ELSE 
    output = 'positive'
END IF

END SUBROUTINE sub_negative_or_not

This is the output:

FUNCTION: -9 is negative
SUBROUTINE: -9 is negative
 Expected negative.
FUNCTION:  7 is negative
SUBROUTINE:  7 is negative
 Expected positive.

As you can see, it appears that once the function or subroutine is called once, the logical variable negative, if switched to .TRUE., remains as such despite the initialization of negative to .FALSE. in the type declaration statement.

I could, of course, correct this problem by just adding a line negative = .FALSE. after declaring the variable in my function and subroutine.

However, it seems very odd to me that this be necessary.

For the sake of portability and code reusability, shouldn't the language (or compiler maybe) require re-initialization of all internal variables each time the subroutine or function is called?

3 Answers
Related