Search code examples
fortran

Assign subroutine output to a variable or call a subroutine as an argument of another subroutine


I am looking to have a subroutine be called and use what is called from there to be put into another subroutine. The setup is similar to what I have below and I want to either have the output of a subroutine be assigned to a variable or use the output as an argument inside of a different calling of a subroutine.

program start
  implicit none
  character(len=40) :: arg1, arg2, input1, input2, input3
  arg1 = "file_name.txt"
  input1 = "Some input"
  input2 = "More input"
  input3 = "Final input"
  ! I either want this below
  arg2 = call two(input1, input2, input3)

  call one(arg1, 12, arg2)

  ! Or this
  call one(arg1, 12, call two(input1, input2, input3))

end program start

subroutine one(arg1, arg2, arg3)
  implicit none
  character(len=40) :: arg1, arg2, arg3
  open(arg1, arg2)
  write(arg2, '(a)') arg3
end subroutine one

subroutine two(input1, input2, input3)
  implicit none
  character(len=40) :: input1, input2, input3
  character(len=120) :: output
  output = input1 // NEW_LINE('A') // input2 // NEW_LINE('A') // input3
   
end subroutine two
  

Solution

  • In Fortran the syntax for the call statement for calling a subroutine is simply call <subroutine name>([arg1[,arg2[...]]]), no other usages are allowed as far as I remember.

    What you have in your mind, as remarked in the notes, is probably a function, which in fortran is invoked without the call keyword, it returns a single variable as a result (possibly an array or a derived type or a combination of them) and the result is syntactically usable in an expression and thus as an argument to another function or subroutine call.

    Something in the lines of (sorry for the different use of upper/lower case, that's a matter of style):

    PROGRAM funfun
    CALL p3(f1(f2(4.)))
    END PROGRAM funfun
    
    REAL FUNCTION f1(x)
    REAL,INTENT(in) :: x
    f1 = x**2
    END FUNCTION f1
    
    REAL FUNCTION f2(x)
    REAL,INTENT(in) :: x
    f2 = x**3
    END FUNCTION f2
    
    SUBROUTINE p3(x)
    REAL,INTENT(in) :: x
    PRINT*,'The result is',x
    END SUBROUTINE p3
    

    By the way, in your program you are already making use of the (intrinsic) function NEW_LINE.