I have a main program and two modules, where one module defines input used throughout the subroutines of the main program (call it commons) and the other one evaluates a function (call it mixture_mod). From the main program I call a subroutine in mixture_mod and pass some input. I would like that input to be "global" for the mixture_mod, because the subroutine uses another subroutine with the same input. The variables in two modules have the same names, and I believe that IMPLICIT NONE and PRIVATE should isolate the input variables in mixture_mod from the rest of the program. It seems not to be the case, as I receive the errors:
error #6279: A specification expression object must be a dummy argument, a COMMON block object, or an object accessible through host or use association [NVR]
error #6841: An automatic object must not appear in the specification part of a module.
I am wondering if there is a way to isolate variable names in mixture_mod so that they do not clash with the same names used in the main program? A solution could be to rename the variables, but I am not sure this is sufficient as I would like mixture_mod to be able to stand along from the rest of the program. Or maybe this is not what causes the errors, but what then?
Thank you in advance. The code is provided.
MODULE MIXTURE_MOD IMPLICIT NONE PRIVATE PUBLIC :: getmixture INTEGER(4) :: nvr,nfk,nx REAL(8) :: x(nvr,nx),qw(nx),logphi(nx) CONTAINS SUBROUTINE getmixture(nvr0,nx0,qx,qw0,logphi0,nfk0,th) INTEGER(4),INTENT(IN) :: nvr0,nx0 INTEGER(4),INTENT(OUT) :: nfk0 REAL(8),INTENT(IN) :: qx(nvr0,nx0),qw0(nx0),logphi0(nx0) REAL(8),ALLOCATABLE,INTENT(OUT) :: th(:) REAL(8) :: th0(6),fstar INTEGER(4) :: k nvr=nvr0; nx=nx0; x=qx; qw=qw0; logphi=logphi0; nfk=1; k=6; th0=0d0; CALL fcn(k,th0,fstar); nfk0=nfk; ALLOCATE(th(6)); th=th0; END SUBROUTINE getmixture SUBROUTINE fcn(npk,th_f,fd) IMPLICIT NONE INTEGER(4), INTENT(IN) :: npk REAL(8), INTENT(IN) :: th_f(npk) REAL(8), INTENT(OUT) :: fd !Uses specification part of the module as intermediate input fd=1d0; END SUBROUTINE fcn END MODULE MIXTURE_MOD MODULE commons IMPLICIT NONE SAVE INTEGER(4) :: nvr,nfk,nk,nx REAL(8),ALLOCATABLE :: qw(:),x(:,:),logphi(:) END MODULE commons PROGRAM test USE commons USE MIXTURE_MOD IMPLICIT NONE REAL(8),ALLOCATABLE :: th1(:) nvr=2; nk=5 ; nx=nk**nvr ALLOCATE(qw(nx),x(nvr,nx),logphi(nx)) x=1d0; qw=1d0; logphi=1d0 CALL getmixture(nvr,nx,x,qw,logphi,nfk,th1) END PROGRAM test
The problem you have here is not the names but that you've declared module variables x, qw and logphi as arrays whose bounds are other module variables. This doesn't work - module variables are static and come into existence when the program starts - you can't later assign values to the bounds.
What you want to do here instead is make these arrays ALLOCATABLE with deferred-shape bounds, like this:
REAL(8), ALLOCATABLE :: x(:,:),qw(:),logphi(:)
and then allocate them to the desired size when the program starts (probably by calling a procedure in the module to do it.)
As for names, you're right that there can be a conflict if a procedure that USEs the module declares local variables of the same name. If the module variables are used only in the module, then make them PRIVATE. Otherwise consider naming them with a prefix that makes them unique.