Alex Eftimiades
Alex Eftimiades

Reputation: 2617

How to call a function internal to a subroutine in a module?

I have a module that contains a subroutine which in turn contains a function. I say use themodule in my main program and I can call thesubroutine, but how do I access the function that is contained in the subroutine?

The code looks like this:

module useful
  integer, parameter :: N=2
  double precision, parameter :: xmin=1, xmax=10, pi=3.1415926535898
  double complex :: green(N,N), solution(N), k=(2.0,0.0)
contains
  subroutine y(n1)
  contains
    function x(n1)
      real :: n1, x
      x=n1*(xmax-xmin)/N
    end function x
  end subroutine y
end module useful

Upvotes: 8

Views: 34350

Answers (4)

Albert S. Kim
Albert S. Kim

Reputation: 1

To call function x from subroutine y, write

public :: x

(right) before contains.

Upvotes: 0

arclight
arclight

Reputation: 1608

To clarify the answer given by M. S. B., split up your code as follows, noting how function x() has been extracted from subroutine y() and there's only a single 'contains' statement to separate module-level variable declarations from function/subroutine declarations:

module useful

  integer, parameter :: N=2
  double precision, parameter :: xmin=1, xmax=10, pi=3.1415926535898
  double complex :: green(N,N), solution(N), k=(2.0,0.0)

contains

  subroutine y(n1)
    real :: n1
    ! Here you can do something like:
    ! print 'F8.3', x(n1) 
  end subroutine y

  function x(n1)
    real :: n1, x
    x=n1*(xmax-xmin)/N
  end function x

end module useful

As M. S. B. points out, x() and y() are in the same scope so there's nothing special you need to do to call x() from y().

Upvotes: 4

zmi
zmi

Reputation: 94

Some additional remarks. You can put the function inside the subroutine, if this function is used by this subroutine only. In this case nesting the functions is a useful concept.

If you want to hide some functions in the module for the external program (forever), you declare those hidden functions as private in your module.

i.e

module useful
public y,x ! shall be accessible by "use useful" statement in external program 
private ! anything else declared in the module is hidden for external program
integer, parameter :: N=2
!...

contains

subroutine y(n1)

end subroutine y

function x(n1)

end function x

end module useful

using public and private helps you to avoid mistakes with contamination of your namespace by using the statements

use useful, only: y,x

use useful2, only: x,y,z

use useful3, only: x2,x3,x4

Upvotes: 5

M. S. B.
M. S. B.

Reputation: 29381

You should not contain the function inside the subroutine. Have the function after the subroutine. Just have as many procedures (subroutines & functions) in the module as you need. Start each with a subroutine or a function statement and end them with their corresponding end statement. Do not nest them inside each other ... instead, one after the other. Have only the module contains statement. Then "use" that module from your main program, or from a procedure outside of the module.

The subroutines and functions in the module are also accessible to each other. No need to use a "contains".

Upvotes: 9

Related Questions