I\'ve noticed that variables in a (child) module, which are used by a parent modules are accessible in a main program through just the parent module. This is one concept which c
Though not inituitve like IDE, gfortran can print a list of imported symbols by attaching the -fdump-fortran-original
(or -fdump-parse-tree
) option. To do so, we first generate *.mod file as
gfortran -c {c,b,a}.f90
and compile the desired source as
gfortran -fdump-fortran-original -c test.f90
Then, we get a list of imported symbols like this:
Namespace: A-Z: (UNKNOWN 0)
procedure name = test
symtree: 'a' || symbol: 'a'
type spec : (INTEGER 4)
attributes: (VARIABLE IMPLICIT-SAVE USE-ASSOC(a_mod))
symtree: 'a_mod' || symbol: 'a_mod'
type spec : (UNKNOWN 0)
attributes: (MODULE USE-ASSOC(a_mod))
symtree: 'b' || symbol: 'b'
type spec : (INTEGER 4)
attributes: (VARIABLE IMPLICIT-SAVE USE-ASSOC(b_mod))
symtree: 'b_mod' || symbol: 'b_mod'
type spec : (UNKNOWN 0)
attributes: (MODULE USE-ASSOC(b_mod))
symtree: 'c' || symbol: 'c'
type spec : (INTEGER 4)
attributes: (VARIABLE IMPLICIT-SAVE USE-ASSOC(c_mod))
symtree: 'c_mod' || symbol: 'c_mod'
type spec : (UNKNOWN 0)
attributes: (MODULE USE-ASSOC(c_mod))
symtree: 'inc_c' || symbol: 'inc_c' <---
type spec : (UNKNOWN 0) <---
attributes: (PROCEDURE MODULE-PROC USE-ASSOC(c_mod) SUBROUTINE) <---
symtree: 'test' || symbol: 'test'
type spec : (UNKNOWN 0)
attributes: (PROGRAM PUBLIC SUBROUTINE)
(For example, the lines with arrow indicates that a routine inc_c
is available from c_mod
.) If we modify test.f90 so as to attach the only
keyword,
program test
use a_mod, only: inc_c
implicit none
call inc_c
end program
then the output is also simplified accordingly:
Namespace: A-Z: (UNKNOWN 0)
procedure name = test
symtree: 'a_mod' || symbol: 'a_mod'
type spec : (UNKNOWN 0)
attributes: (MODULE USE-ASSOC(a_mod))
symtree: 'inc_c' || symbol: 'inc_c'
type spec : (UNKNOWN 0)
attributes: (PROCEDURE MODULE-PROC USE-ASSOC(c_mod) SUBROUTINE)
symtree: 'test' || symbol: 'test'
type spec : (UNKNOWN 0)
attributes: (PROGRAM PUBLIC SUBROUTINE)
So, althogh I've never used this option for this purpose, it might be of some use for the OP's purpose (if really necessary).
As Vladimir F suggested in a comment, you can solve this issue using private
and public
statements in your modules. If you rewrite your modules like this:
module a_mod
use :: b_mod
private
public :: a
integer :: a
end module
module b_mod
use :: c_mod
private
public :: b
integer :: b
end module
module c_mod
private
public :: c, inc_c
integer :: c = 10
contains
subroutine inc_c
c = c + 10
end subroutine
end module
In this case, the statement private
in the beginning of each module means that quantities declared in the module are not exported by default. You now have to explicitly declare what variables and subroutines to make available when you use
the module by adding a public
statement. (This could alternatively be done in one line using the syntax integer, public :: c = 10
.) This practice prevents c_mod
variables from leaking out of b_mod
, and so on.
The best thing to do, in my opinion, is to avoid the use of blanket use
statements, especially for large and sometimes unwieldy modules. Instead, specify which module entities to inherit via the only
keyword, such as:
program main
use a_mod, only : c, inc_c
implicit none
call inc_c
write(*,*) c
end program main
This works, but it's confusing because a_mod
isn't the real owner of c
and inc_c
. Therefore, you should try to use
entities from where they are actually declared, which gives:
program main
use c_mod, only : c, inc_c
! ^ This has changed
implicit none
call inc_c
write(*,*) c
end program main
Now, anybody reading the code has a clear notion of which variables and subroutines are in scope and where they come from.
Finally, this has the added benefit of reducing the risk that you use c
without realizing it's actually inhereted from c_mod
. This is particularly a problem when not using implicit none
!