View Single Post
  #8 (permalink)  
Old 04-24-2012, 04:43 PM
Ron Shepard
Guest
 
Posts: n/a
Default Re: Confusion with variables in modules

In article <1kj1pyw.s6yvn6r10s8gN%nospam@see.signature>,
nospam@see.signature (Richard Maine) wrote:

> Wolfgang Kilian <seesig@domain.invalid> wrote:
>
> > On 04/24/2012 11:38 AM, Marco Zannoni wrote:
> > > Il giorno marted́ 24 aprile 2012 10:09:08 UTC+2, Arjen Markus ha scritto:

>
> > >> If you want to limit the accessibility and use these variables only as a
> > >> means to share information within the module, you can use the PRIVATE
> > >> attribute or statement:
> > >>
> > >> integer, private :: k = 0

>
> > > Thanks, this was exaclty what I was looking for.

> >
> > You may consider setting the _default_ accessibility of all module
> > entities to private, and mark only those entities as public that you
> > really need outside the module.

>
> That's what I recommend. To do so, just use the PRIVATE statement with
> no particular entities specified, as in just
>
> private
>
> This goes right by the "implicit none" (which I do see that the OP
> uses). With modules, "implicit none" becomes even more important because
> without it you can't easily tell whether a variable is implicitly
> declared or accessed from a module.


There are two aspects of the original question. One if if you are
writing a module that will be used by other programmers, and you
want to protect the module variables that are intended to be shared
only within the module. I think the above comments address mostly
this situation. You declare some or all of the module variables to
be private, and except for some trickery, those variables will not
be visible or accessible directly outside of the module. The
"trickery" involves pointers or using those private variables as
actual arguments to other subroutines (which then can modify them,
perhaps intentionally or perhaps by mistake).

The other situation is when you are on the other side and you are
USEing a module (written by you or by someone else). If you don't
want to modify any of the module variables by mistake, and you want
the compiler to help you avoid doing that, then you can develop the
programming habit of always using the ONLY clause with the USE
statements. This is useful in several ways. In addition to the
unintentional modification problems this avoids, it also documents
in the USEing subroutine exactly where particular variables live (or
at least how you are accessing them, which is not quite the same
thing, but you probably see the difference). Consider the following

use mod1
use mod2
use mod3
implicit none
...

k = k + 1
...

You know that "k" must be in one of those modules because otherwise
the compiler would complain (due to the implicit none and the lack
of a local declaration). But you don't know which one, and to track
it down you would need to search through the source to all those
modules (or worse, dig down several levels of modules to find it,
with the breadth of your search increasing exponentially with the
depth). If instead, you had written

use mod1, only: a, b, c
use mod2, only: i, j, k
use mod3, only: x, y, z
...

then it would be clear at a glance how "k" became accessible in your
code. If you then look in module mod2, and if it also uses ONLY
clauses like this, then you could quickly track down exactly where
that variable was declared. You could also search your code for
other "use mod2" statements to see where else that variable has been
made accessible.

As nice as all this sounds, one complaint I have is that it is
simply a programming convention. If you slip up somewhere and USE
mod2 without the only clause, then you are back with all of the
original problems. You just shot yourself in the foot, and you
might not know about it until some multiday debugging excursion to
track down some problem with a variable being modified. Currently,
there is no way to enforce the requirement that ONLY clauses must be
used (say, IMPLICIT ONLY NONE or REQUIRE ONLY or some similar
declaration) so that the compiler can help you enforce this. You
are just on your own to try to enforce your chosen programming
convention with little or no additional help available from the
compiler.

$.02 -Ron Shepard
Reply With Quote