I was under the impression that the main differences between subroutines and functions in Fortran was that functions returned values, while subroutines change some or all of the values passed as arguments. But then I learned that you could modify variables passed in to functions as arguments too. I'm confused, and can't find a good reference for the differences between them.
So, what are the differences between the two constructs, and when and why should one be preferred over the other?
Functions and subroutines operate similarly but have one key difference. A function is used when a value is returned to the calling routine, while a subroutine is used when a desired task is needed, but no value is returned.
The purpose of a function is to take in a number of values or arguments, do some calculations with those arguments and then return a single result. There are some functions which are written into FORTRAN and can be used without any special effort by you, the programmer. They are called intrinsic functions.
A function is defined with the function statement and a subroutine with subroutine . In a definition of procedure, all the arguments should be declared as variables with intent . A function should return a single value, but a subroutine does not have to return values or can return any number of values.
Whether to use one or another is more or less a matter of programming style. You are allowed to write the arguments of both functions and subroutines as intent(in)
, intent(inout)
or intent(out)
.
My personal style is however to only use the intent(in)
arguments for functions, which is also a requirement for pure
functions. An exception to this rule can be made when en error code intent(out)
argument is necessary.
There is a subtle trap hidden in functions which return different results for the same input argument value. Consider a hypothetical function returning a random number
real function rnd()
end function
calling it once
x = rnd()
is completely OK. Calling it multiple times in a single expression
x = (rnd() + rnd()) / 2
can result in the function being called only once. Fortran language rules allow such behaviour. Therefore, the standard Fortran procedure for getting random numbers random_number()
is a subroutine (and because all intrinsic functions are pure
).
Where ever you cannot use a function, use a subroutine.
Any function can by converted to a subroutine by moving the result variable to a dummy argument with intent(out)
. The opposite process may be more problematic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With