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 clearly distinguishes use
statement in Fortran from include
statement in C/C++. The following programs clearly illustrate this concept.
a.f90
module a_mod
use b_mod
implicit none
integer :: a
end module
b.f90
module b_mod
use c_mod
implicit none
integer :: b
end module
c.f90
module c_mod
implicit none
integer :: c = 10
contains
subroutine inc_c
c = c + 10
end subroutine inc_c
end module
test.f90
program test
use a_mod
implicit none
call inc_c
write(*,*),c
end program
Note that I am able to call a function in c_mod
by just using a_mod
. Note that I cannot directly observe that c_mod
is available unless I traverse the dependency list.
But in a complicated software, is there a simple way to know (say, using an IDE) if a variable is available for use at a particular line?
As Vladimir F suggested in a comment, you can solve this issue using
private
andpublic
statements in your modules. If you rewrite your modules like this: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 youuse
the module by adding apublic
statement. (This could alternatively be done in one line using the syntaxinteger, public :: c = 10
.) This practice preventsc_mod
variables from leaking out ofb_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 theonly
keyword, such as:This works, but it's confusing because
a_mod
isn't the real owner ofc
andinc_c
. Therefore, you should try touse
entities from where they are actually declared, which gives: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 fromc_mod
. This is particularly a problem when not usingimplicit none
!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 asand compile the desired source as
Then, we get a list of imported symbols like this:
(For example, the lines with arrow indicates that a routine
inc_c
is available fromc_mod
.) If we modify test.f90 so as to attach theonly
keyword,then the output is also simplified accordingly:
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).