I have a FORTRAN file "testValueKeyword.for" contains following code
subroutine intersub2(x,y)
integer, value :: x
integer y
x = x + y
y = x*y
print *, 'in subroutine after changing: ', x, y
end subroutine
program testValueKeyword
integer :: x = 10, y = 20
print *, 'before calling: ', x, y
call intersub(x, y)
print *, 'after calling: ', x, y
x = 10
y = 20
call intersub2(x, y)
contains
subroutine intersub(x,y)
integer, value :: x
integer y
x = x + y
y = x*y
print *, 'in subroutine after changing: ', x, y
end subroutine
end program
the subroutine intersub and intersub2 contain the same code, both passing the x argument by value, but the intersub2 seems passing a large random integer similar to memory address. I get different y values after running. could you explain this to me?
Place subroutine intersub2 into a module and use
that module from the caller, here program testValueKeyword, so that the caller "knows" the calling convention to use. When you use "advanced" argument features of Fortran >=90 in a procedure (subroutine or function), you need to make the interface explicit to the caller so that the caller uses the same interface / calling conventions as the procedure. Otherwise an inconsistency between caller and callee will cause "random" communication between the two. The easiest way to make the interface known is to place the procedure into a module and use
that module. You could also describe the procedure with an interface
, but that's more work and a second thing to maintain.
When I compile your code with gfortran with extensive warning options, gfortran even tells me of the problem:
call intersub2(x, y)
1
Error: Dummy argument 'x' of procedure 'intersub2' at (1) has an attribute that requires an explicit interface for this procedure
If you are using gfortran, try these compiler options for debugging: -O2 -fimplicit-none -Wall -Wline-truncation -Wcharacter-truncation -Wsurprising -Waliasing -Wimplicit-interface -Wunused-parameter -fwhole-file -fcheck=all -std=f2008 -pedantic -fbacktrace