Search code examples
fortransubroutine

Fortran subroutine value keyword


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?


Solution

  • 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