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

Local variable changes

gib
New Contributor II
314 Views

This is more an observation than a question, but there is an implicit question.

I have a subroutine subx that includes

real(8) :: rtol = 1.0e-5

In this subroutine another subroutine suby is called with rtol one of the arguments.  Apparently this other subroutine changes rtol.  In IVF the behaviour is as I expected: in every call to subx the value of rtol passed to suby is 1.0e-5.  But when the program is built with gfortran there is an error, since the value of rtol in subx changes with each call (because it is changed by suby).  For gfortran it was necessary to add this line

rtol = 1.0e-5

before the call to suby.  Which behaviour is consistent with the standard?  I often assume the IVF behaviour.

0 Kudos
4 Replies
Arjen_Markus
Honored Contributor I
314 Views

The behaviour that you describe for gfortran is standard-compliant. The behaviour you describe for Intel Fortran is not: with such an initialisation the variable gets the SAVE attribute and it receives its value at the beginning of the program, not at the (repeated) start of the subroutine.

However, I checked the behaviour with a small program and found that Intel Fortran and gfortran follow the standard:

module xx
    implicit none
contains
subroutine subx
    real(8) :: rtol = 2.34e-5_8

    call suby( rtol )
    write(*,*) rtol
end subroutine subx

subroutine suby( rt )
    real(8) :: rt

    write(*,*) 'On input', rt
    rt = 1.0_8
end subroutine suby
end module xx

program testxx
    use xx
    implicit none

    call subx
    call subx
end program testxx

With both compilers resulting in the following output:

 On input  2.340000000000000E-005
   1.00000000000000     
 On input   1.00000000000000     
   1.00000000000000     

So with what version of Intel Fortran do you get the described behaviour?

0 Kudos
andrew_4619
Honored Contributor II
314 Views

In ifort the compile options effect this , look at \qsave and \qauto .

Having said that the assignment on the declaration is at compile time and it has to be given SAVE status so if the program later redefines that value then the initialisation is history. You really need to assign the value on each entry to the subroutine if that is what you need. 

0 Kudos
mecej4
Honored Contributor III
314 Views

Gib wrote:
In this subroutine another subroutine suby is called with rtol one of the arguments.  Apparently this other subroutine changes rtol.  In IVF the behaviour is as I expected: in every call to subx the value of rtol passed to suby is 1.0e-5.

Your expectation is wrong; I suspect that you are misinterpreting the behaviour of your previous program(s). 

If a variable (scalar or array) with or without the SAVE attribute, is (i) passed as an argument to a subroutine, and the corresponding dummy argument has no INTENT specified, (ii) has one or more components changed in the subroutine, (iii) after returning from the subroutine the changes to the values will remain.

Any compiler that did what you described would quickly be flagged as defective in that regard. For the majority of legacy codes, that compiler would, I suspect, be unusable.

Please present an example where Ifort (any version, but please state the version) does what you said it did.

0 Kudos
gib
New Contributor II
314 Views

mecej4 is correct, it was my mistake.  I developed the code with IVF, then gave it to somebody to use with gfortran. She discovered the error while invoking subx multiple times.  I'd forgotten that I had only tested the code by calling subx once, and leapt to the wrong conclusion.

Sorry for wasting people's time.

0 Kudos
Reply