Go Back   Rhinocerus > Newsgroup > Newsgroup comp.lang.* 1 > Newsgroup comp.lang.fortran

Reply
 
Thread Tools Display Modes
  #16 (permalink)  
Old 05-31-2012, 08:38 AM
Phillip Helbig---undress to reply
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

I was just looking through some old F77 code which was my motivation for
asking this. There are about a dozen routines, and about 4 pairs of
routines which need to share variables (in addition to some variables
shared by many of the routines, but that is not an issue). Making these
variables global module variables is a bit confusing. Having separate
external modules is a possibility, but is also a bit confusing. (It
does have the advantage that they could also be USEd by the calling
program if necessary.) The most elegant solution really would be a USE
statement in a routine contained in a module which USEs (some of the
local variables in) another routine in the same module. This is
self-documenting. If both routines USE an additional module, then this
is not self-documenting.

I don't know how difficult the implementation would be. However, since
the present situation is that local variables are invisible to all other
routines (except internal routines), and USE applies only to a module,
not a routine, USE ROUTINE, ONLY: X, Y would be orthogonal to existing
usage. (If the routine is PUBLIC, one might even contemplate allowing
whatever USEs the main module to also use some stuff from public
routines within that module.)

Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #17 (permalink)  
Old 05-31-2012, 12:37 PM
Phillip Helbig---undress to reply
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

In article <uPIxr.7769$%E2.7141@viwinnwfe01.internal.bigpond. com>, Ian
Harvey <ian_harvey@bigpond.com> writes:

> If we just put aside the teeny tiny complication that processor support
> for submodules is all-but-non-existant, you might one day be able to do...


Right. :-(

Maybe the best way to go is to put ALL variables which are used to
communicate between pairs of routines in an additional module, rather
than have an additional module for each pair. I can then USE this
module. This keeps the main module free of clutter, which is my main
aim here. (For documentation purposes, I could have ONLY as well so
that it is clear which modules use which variables for communication.)

Reply With Quote
  #18 (permalink)  
Old 06-01-2012, 11:00 AM
Phillip Helbig---undress to reply
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

> Maybe the best way to go is to put ALL variables which are used to
> communicate between pairs of routines in an additional module, rather
> than have an additional module for each pair. I can then USE this
> module. This keeps the main module free of clutter, which is my main
> aim here. (For documentation purposes, I could have ONLY as well so
> that it is clear which modules use which variables for communication.)


To summarize: I think the above is the best solution. Again, the
problem: There are many related routines which share many variables and
it makes sense to have them all in one module. However, a few pairs of
modules need to share a few variables between them. They could of
course be among the variables shared by all routines, but this creates
some clutter, especially if the variables are more for technical stuff,
bookkeeping etc and not directly related to the purpose of module from
the user's point of view. In F77 I had COMMON blocks and the
corresponding variables declared only in the pair of routines in
question. Apart from the general problem that the same things are
defined in more than one place (INCLUDE was not standard), this is OK.
Of course, I could also do this in F95 but I prefer module variables to
COMMON. What I like about the COMMON approach here is that the tools
(variables and COMMON blocks) are defined only in the routines which use
them, and are a small part of these routines. Replacing COMMON blocks
one-to-one with MODULEs for shared variables means creating a module at
the same logical level as the main module which contains all the
routines, including those which need to share a few variables with only
one other routine. In other words, what is essentially a small part of
a routine is defined two logical levels too high.

What I would really like to see is the possibility for a routine in a
module to "use" what is essentially a local variable in another routine
in the same module:

module big
contains
subroutine alpha
real :: x, y, z
subroutine beta
real :: a, b, c
use alpha, only: x !maybe another word than "use"
subroutine gamma
subroutine delta
subroutine epsilon
end module big

To make it safe, something similar to TARGET might be useful, e.g.:

subroutine alpha
real :: x, y, z
allow beta, only: x

Does anyone else see a need for this feature? Would it be difficult to
implement technically? Is there a chance to get it into the next
standard?

It could also be useful where the routines involved are not module
routines but routines after a CONTAINS statement in another routine.
The basic goal is to define things at the level they are used, rather
than one level up (i.e. in the routine or module before CONTAINS) or two
levels up (in a separate module which is USEd by those needing the
variables). In this sense, the COMMON solution is more modular than the
solution with modules.

Reply With Quote
  #19 (permalink)  
Old 06-01-2012, 12:56 PM
glen herrmannsfeldt
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

Phillip Helbig---undress to reply <helbig@astro.multiclothesvax.de> wrote:
>> Maybe the best way to go is to put ALL variables which are used to
>> communicate between pairs of routines in an additional module, rather
>> than have an additional module for each pair. I can then USE this
>> module. This keeps the main module free of clutter, which is my main
>> aim here. (For documentation purposes, I could have ONLY as well so
>> that it is clear which modules use which variables for communication.)


> To summarize: I think the above is the best solution. Again, the
> problem: There are many related routines which share many variables and
> it makes sense to have them all in one module. However, a few pairs of
> modules need to share a few variables between them. They could of
> course be among the variables shared by all routines, but this creates
> some clutter, especially if the variables are more for technical stuff,
> bookkeeping etc and not directly related to the purpose of module from
> the user's point of view.


It is nice to group related variables together. Sometimes there
are clear groupings and it makes sense to follow them.

I don't understand, though, the "technical stuff, bookkeeping."

It seems that one might have one module with all such variables
(and no procedures). Maybe, though, they should go into a structure
passed as an argument to different routines.

> In F77 I had COMMON blocks and the
> corresponding variables declared only in the pair of routines in
> question. Apart from the general problem that the same things are
> defined in more than one place (INCLUDE was not standard), this is OK.
> Of course, I could also do this in F95 but I prefer module variables to
> COMMON.


Put all the variables in a module and USE it in the appropriate
places.

> What I like about the COMMON approach here is that the tools
> (variables and COMMON blocks) are defined only in the routines which use
> them, and are a small part of these routines. Replacing COMMON blocks
> one-to-one with MODULEs for shared variables means creating a module at
> the same logical level as the main module which contains all the
> routines, including those which need to share a few variables with only
> one other routine. In other words, what is essentially a small part of
> a routine is defined two logical levels too high.


I don't understand this. Yes, at some point module variables are
all at the same level. They are all static, there is no nesting
level, for example.

> What I would really like to see is the possibility for a routine in a
> module to "use" what is essentially a local variable in another routine
> in the same module:


> module big
> contains
> subroutine alpha
> real :: x, y, z
> subroutine beta
> real :: a, b, c
> use alpha, only: x !maybe another word than "use"
> subroutine gamma
> subroutine delta
> subroutine epsilon
> end module big


> To make it safe, something similar to TARGET might be useful, e.g.:


> subroutine alpha
> real :: x, y, z
> allow beta, only: x


> Does anyone else see a need for this feature? Would it be difficult to
> implement technically? Is there a chance to get it into the next
> standard?


Well, since Fortran 95 local variables can be automatic, and
they have to be in the case of RECURSIVE. They don't exist before
a routine is called, or after it returns. Note, though, that
they are available to internal procedures. Does that help?

> It could also be useful where the routines involved are not module
> routines but routines after a CONTAINS statement in another routine.
> The basic goal is to define things at the level they are used, rather
> than one level up (i.e. in the routine or module before CONTAINS) or two
> levels up (in a separate module which is USEd by those needing the
> variables). In this sense, the COMMON solution is more modular than the
> solution with modules.


As well as I know it, there is a very close relationship between
MODULE variables and COMMON variables. You USE them differently,
and the ways to misuse them are different, but otherwise they
are very similar.

-- glen
Reply With Quote
  #20 (permalink)  
Old 06-01-2012, 03:38 PM
Richard Maine
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de>
wrote:

> What I like about the COMMON approach here is that the tools
> (variables and COMMON blocks) are defined only in the routines which use
> them, and are a small part of these routines. Replacing COMMON blocks
> one-to-one with MODULEs for shared variables means creating a module at
> the same logical level as the main module which contains all the
> routines, including those which need to share a few variables with only
> one other routine. In other words, what is essentially a small part of
> a routine is defined two logical levels too high.


I still don't see this alleged difference between COMMON and modules for
the purpose you describe. As Glen notes, they are both global. Just
because you put the declarations for a COMMON only in the routines in
question, that doesn't mean that the COMMON is somehow local to them. It
is still global in exactly the same way that a module is global. Each
COMMON can map one-to-one onto a module with exactly the same variables.
I don't see this "level" difference.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
Reply With Quote
  #21 (permalink)  
Old 06-02-2012, 12:53 AM
Ron Shepard
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

In article <1kl04zu.11pk0hkfdcc0kN%nospam@see.signature>,
nospam@see.signature (Richard Maine) wrote:

> Phillip Helbig---undress to reply <helbig@astro.multiCLOTHESvax.de>
> wrote:
>
> > What I like about the COMMON approach here is that the tools
> > (variables and COMMON blocks) are defined only in the routines which use
> > them, and are a small part of these routines. Replacing COMMON blocks
> > one-to-one with MODULEs for shared variables means creating a module at
> > the same logical level as the main module which contains all the
> > routines, including those which need to share a few variables with only
> > one other routine. In other words, what is essentially a small part of
> > a routine is defined two logical levels too high.

>
> I still don't see this alleged difference between COMMON and modules for
> the purpose you describe. As Glen notes, they are both global. Just
> because you put the declarations for a COMMON only in the routines in
> question, that doesn't mean that the COMMON is somehow local to them. It
> is still global in exactly the same way that a module is global. Each
> COMMON can map one-to-one onto a module with exactly the same variables.
> I don't see this "level" difference.


I also don't see exactly what the problem is. From what I can
understand from the previous posts, something like the following
seems like an obvious and straightforward solution:

module integer_vars
integer :: i, j, k
end module integer_vars

module real_vars
real :: a, b, c
end module real_vars

module subs
contains
subroutine suba
use integer_vars, only: i, j, k
...
end subrouitne suba
subroutine subb
use integer_vars, only: i, j, k
...
end subroutine subb
subroutine subc
use real_vars, only: a, b, c
...
end subroutine subc
subroutine subd
use real_vars, only: a, b, c
...
end subroutine subd
subroutine sube
use integer_vars, only: i, j, k
use real_vars, only: a, b, c
...
end subroutine sube
end module subs

Routines suba and subb share just the integer variables, routines
subc and subd share just the real variables, and routine sube uses
both subsets.

Routines that need the integer_vars use that module, routines that
need the real_vars use that module, and modules that need both sets
of variables use both modules. The USE statements document clearly
which variables are being used at any point.

You can also do something like:

module all_vars
use integer_vars: only: i, j, k
use real_vars: only: a, b, c
end module all_vars

and then you could use just this module in those cases where you
want access to all of the variables. This hides the underlying
organization in those cases where it is not important or where you
don't want it to be exposed. You could also define a some_vars
module that uses some particular subset of all the variables. You
can't do this kind of thing with COMMON variables, it is one of many
advantages of modules over COMMON blocks. Except for naming the
modules on the END MODULE statement, I think this is all just f90,
nothing related to submodules or anything in the more recent
language versions is required. The above can all be in one file, or
if it makes better sense the modules could be put in separate files.

The idea of making local variables in one routine visible to another
routine seems really bad to me. For many reasons. The the main one
is that it would allow a local variable to just magically change
value in the middle of an execution sequence with no clue to the
programmer what might be happening. That's not supposed to happen,
no way no how. The above straightforward approach makes the data
usage obvious and clear. You can tell from the local declaration
which variables might change in contrast to the local variables that
don't and can't change. There are also issues with some variables
being implicitly saved, with automatic variables that are no longer
in scope being referenced, and (as others have mentioned) ambiguity
with local variables for recursive routines being referenced
externally. The whole idea just doesn't make sense.

$.02 -Ron Shepard
Reply With Quote
  #22 (permalink)  
Old 06-02-2012, 01:08 AM
Terence
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

I had almost finished a long posting to explain why most CLF postings are
now about installing compilers, successfully using them, or finding how to
express a simple F77 process in F90/95 or later code. I.e. complexity is
crippling productivity and comprehension of other's code

Then I read Phillip's posting and found he had matched exactly my own
posting of years ago, of my decription of trying to acheive something in
F90/95 that was SO simple in F77 (passing language text tables with the text
length counts, the text and the message number, using a COMMON block). It
was never solved by the Fortran community, in spite of a lot of suggestions,
and again, I stayed with F77.

"If it isn't broken, don't try to fix it".


Reply With Quote
  #23 (permalink)  
Old 06-02-2012, 01:10 AM
Terence
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

Again! Exactly, Phillip!


Reply With Quote
  #24 (permalink)  
Old 06-02-2012, 01:18 AM
Terence
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

Glen suggested:-
>Put all the variables in a module and USE it in the appropriate places.


And that what was most commonly (actually a pun) suggested for my problem,
too.
But if the (language table) text contents and message lengths have to read
in first and parsed, it just raises another level of complexity; where is
the external file reading to be done?.
COMMON worked; other methods didn't.


Reply With Quote
  #25 (permalink)  
Old 06-02-2012, 04:09 AM
Ron Shepard
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

In article <9Idyr.7823$%E2.3568@viwinnwfe01.internal.bigpond. com>,
"Terence" <tbwright@bigpond.net.au> wrote:

> I had almost finished a long posting to explain why most CLF postings are
> now about installing compilers,


Yes, there are some of those.

> successfully using them,


Yes, those too.

> or finding how to
> express a simple F77 process in F90/95 or later code.


There are very few of those. In fact, I don't even remember the one
you are talking about, and that is probably the only one in the past
year or two.

> I.e. complexity is
> crippling productivity and comprehension of other's code


When you begin with an incorrect premise, you draw incorrect
conclusions.

>
> Then I read Phillip's posting and found he had matched exactly my own
> posting of years ago, of my decription of trying to acheive something in
> F90/95 that was SO simple in F77 (passing language text tables with the text
> length counts, the text and the message number, using a COMMON block).


Odd. My previous post explained several things that could be done
with modules that cannot be done with common blocks.

> It
> was never solved by the Fortran community, in spite of a lot of suggestions,
> and again, I stayed with F77.
>
> "If it isn't broken, don't try to fix it".


I expect you are in a small minority with your opinion. Perhaps a
minority of one.

$.02 -Ron Shepard
Reply With Quote
  #26 (permalink)  
Old 06-02-2012, 09:23 AM
Phillip Helbig---undress to reply
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

In article <jqae6n$1mf$1@speranza.aioe.org>, glen herrmannsfeldt
<gah@ugcs.caltech.edu> writes:

> It is nice to group related variables together. Sometimes there
> are clear groupings and it makes sense to follow them.
>
> I don't understand, though, the "technical stuff, bookkeeping."


Suppose the module is concerned with calculating some quantity and this
is done partly through numerical integration. There might be some
low-level variables in a couple of routines which might save previously
calculated results, flag errors, collect statistics for debugging etc
which are conceptually independent of the real purpose of the module and
certainly not of interest to the calling program.

> Put all the variables in a module and USE it in the appropriate
> places.


Right; this is what I concluded is the best solution.

> > What I like about the COMMON approach here is that the tools
> > (variables and COMMON blocks) are defined only in the routines which use
> > them, and are a small part of these routines. Replacing COMMON blocks
> > one-to-one with MODULEs for shared variables means creating a module at
> > the same logical level as the main module which contains all the
> > routines, including those which need to share a few variables with only
> > one other routine. In other words, what is essentially a small part of
> > a routine is defined two logical levels too high.

>
> I don't understand this. Yes, at some point module variables are
> all at the same level. They are all static, there is no nesting
> level, for example.


Technically, yes, but aesthetically, no. :-)

The structure with COMMON is

module main
global variables
routine alpha
local variables a, b, c
routine beta
local variables a, b, c
common /both/ x, y
routine gamma
local variables a, b, c
routine delta
local variables a, b, c
routine epsilon
local variables a, b, c
common /both/ x, y
routine zeta
local variables a, b, c

so x and y are defined in beta and epsilon, where they are used.

The alternatives are

module main
global variables
x, y
routine alpha
local variables a, b, c
routine beta
local variables a, b, c
routine gamma
local variables a, b, c
routine delta
local variables a, b, c
routine epsilon
local variables a, b, c
routine zeta
local variables a, b, c

In this case, x and y are clutter since they are visible to all
routines, though only a couple use them. In contrast to some of the
other module variables, the calling program doesn't care about them.
They are also defined a level higher than where they are used.

or

module main
global variables
routine alpha
local variables a, b, c
routine beta
use both
local variables a, b, c
routine gamma
local variables a, b, c
routine delta
local variables a, b, c
routine epsilon
use both
local variables a, b, c
routine zeta
local variables a, b, c
module both
x, y

This keeps x and y visible only where they are used (and, in contrast to
common, defines them at only one place), but it means an extra module,
which is on the same logical level as the main module, though it is
concerned with variables used within a procedure contained within the
main module. For another pair, I would have

module main
global variables
routine alpha
local variables a, b, c
routine beta
use betaepsilon
local variables a, b, c
routine gamma
use gammadelta
local variables a, b, c
routine delta
use gammadelta
local variables a, b, c
routine epsilon
use beta epsilon
local variables a, b, c
routine zeta
local variables a, b, c
module both betaepsilon
x, y
module both gammadelta
x, y

which means an additional module for each subset. I think this is
better:

module main
global variables
routine alpha
local variables a, b, c
routine beta
use both, only: x, y
local variables a, b, c
routine gamma
use both, only: v, w
local variables a, b, c
routine delta
use both, only: v, w
local variables a, b, c
routine epsilon
use both, only: x, y
local variables a, b, c
routine zeta
local variables a, b, c
module both
x, y, v, w

> > What I would really like to see is the possibility for a routine in a
> > module to "use" what is essentially a local variable in another routine
> > in the same module:

>
> > module big
> > contains
> > subroutine alpha
> > real :: x, y, z
> > subroutine beta
> > real :: a, b, c
> > use alpha, only: x !maybe another word than "use"
> > subroutine gamma
> > subroutine delta
> > subroutine epsilon
> > end module big

>
> > To make it safe, something similar to TARGET might be useful, e.g.:

>
> > subroutine alpha
> > real :: x, y, z
> > allow beta, only: x

>
> > Does anyone else see a need for this feature? Would it be difficult to
> > implement technically? Is there a chance to get it into the next
> > standard?

>
> Well, since Fortran 95 local variables can be automatic, and
> they have to be in the case of RECURSIVE.


ALLOW would tell the compiler that these could be accessed by another
routine.

> They don't exist before
> a routine is called, or after it returns.


Unless they are SAVEd, presumably.

> Note, though, that
> they are available to internal procedures. Does that help?


Not in this case.

> As well as I know it, there is a very close relationship between
> MODULE variables and COMMON variables. You USE them differently,
> and the ways to misuse them are different, but otherwise they
> are very similar.


Indeed. What I like about COMMON in this case (otherwise, I want to
avoid it and use module variables and will probably do so even here) is
that the variables shared between a pair of routines are mentioned there
and nowhere else. With module variables, I have to define them outside
of these routines.

A country is divided into states, counties, towns etc. Imagine two
towns (in different states) have some sort of cooperation. It would be
logical for each one to have an office dealing with this. This is the
COMMON approach. With the module approach, there is either an office in
the national capital which deals with all such cooperations, or there is
an office in a third town which communicates with both towns in the
partnership.

Reply With Quote
  #27 (permalink)  
Old 06-02-2012, 09:25 AM
Phillip Helbig---undress to reply
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

In article <1kl04zu.11pk0hkfdcc0kN%nospam@see.signature>,
nospam@see.signature (Richard Maine) writes:

> I still don't see this alleged difference between COMMON and modules for
> the purpose you describe. As Glen notes, they are both global. Just
> because you put the declarations for a COMMON only in the routines in
> question, that doesn't mean that the COMMON is somehow local to them. It
> is still global in exactly the same way that a module is global. Each
> COMMON can map one-to-one onto a module with exactly the same variables.
> I don't see this "level" difference.


As I noted in my first post from today, it is not a technical
distinction, but more an aesthetic one. Yes, COMMON is a global object.
However, in a chart of the module structure, it is enough to mention the
shared variables only within the routines concerned while with the
module approach they MUST be mentioned OUTSIDE the routines concerned.
Maybe the last paragraph in my other post about cooperation between
towns illustrates what I want to communicate.

Reply With Quote
  #28 (permalink)  
Old 06-02-2012, 09:28 AM
Phillip Helbig---undress to reply
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

In article <ron-shepard-9B8689.19535201062012@news60.forteinc.com>, Ron
Shepard <ron-shepard@NOSPAM.comcast.net> writes:

> I also don't see exactly what the problem is. From what I can
> understand from the previous posts, something like the following
> seems like an obvious and straightforward solution:


Yes, this will work and is functionally the same. See my reply from
today to Richard Maine.

> The idea of making local variables in one routine visible to another
> routine seems really bad to me. For many reasons. The the main one
> is that it would allow a local variable to just magically change
> value in the middle of an execution sequence with no clue to the
> programmer what might be happening. That's not supposed to happen,
> no way no how.


If one were using a module variable visible to more than one routine,
this could also happen. Moreover, ANY routine in which it is visible
could change it. ALLOW alerts the programmer and compiler to this
possibility.

Reply With Quote
  #29 (permalink)  
Old 06-02-2012, 04:01 PM
Ron Shepard
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

In article <jqcm1t$8rs$1@online.de>,
helbig@astro.multiCLOTHESvax.de (Phillip Helbig---undress to
reply) wrote:

> Indeed. What I like about COMMON in this case (otherwise, I want to
> avoid it and use module variables and will probably do so even here) is
> that the variables shared between a pair of routines are mentioned there
> and nowhere else. With module variables, I have to define them outside
> of these routines.


This redundant declaration of common block variables is actually one
of the main problems with common blocks. In f77, there was no way
other than within the separate routines to declare shared data.
(Well, okay you could get clever with multiple entry points to some
extent, but this was rather limited.) It was the responsibility of
the programmer to ensure that these multiple definitions of the
common block variables were all consistent. And since the
individual variables declared within the common block in the
separate routines could have different names, this was sometimes an
almost impossible task in practice. With sequence association
aliasing and mixed real, integer, and double precision variables, it
was truly a mess, particularly regarding portability on machines
where you wanted to change precisions and/or data lengths. And
don't forget that you needed to SAVE these common blocks
consistently everywhere they were declared, something that most
programmers did not know and did not do correctly.

Many f77 compilers supported the (then) nonstandard INCLUDE
statement as an extension. This solved some of the problems by
allowing the common block variables (and the SAVE statement) to be
declared in one place, and then included into the various routines
that needed it. From your statement above, you probably would not
like this approach because it would "require" you to declare the
common block entities in a separate file. Of course this approach
also has several of its own problems, besides the fact that it was a
nonstandard extension, including the reference through a file name
rather than a global entity. File name conventions are OS dependent
and are completely outside of the fortran standard, so this approach
required putting something that was fundamentally nonportable
directly into your source code. Other problems included conflicts
between local variable names and these common block variable names
since there was no way to temporarily rename a common block variable
on the INCLUDE statement. Combined with the fact that IMPLICIT NONE
was also nonstandard in f77, this was all just another big mistake
waiting to happen to the programmer who happened to choose a wrong
variable name for what he thought was a local variable.

You may be too young to have encountered this, but it used to be
fairly common practice to specify overlay structures for data and
code in order to reuse as efficiently as possible the limited memory
that was available to the programmer. Common blocks were specified
by their common block names while subroutines were specified by
their names. In f77 this introduced an asymmetry between the way
these different entities were declared and used. Namely, the data
could only be declared within the subroutines in the source code,
but in the overlay specification they were treated rather
equivalently. And, of course, the programmer had to think of them
equivalently as he was writing the code, so this was another example
of how the f77 program structure was fighting against the
programmer. As computer memories grew larger over time, program
overlays became less common. I don't think I have seen an overlay
linker in over 20 years, and even that one was on a DECSYSTEM-20
originally from the late 70's.

Modules in f90 solved most of these problems. Variables could be
declared in one place, used anywhere they were needed, and renamed
locally if necessary in order to avoid conflicts. The OS-dependent
file name references were eliminated in the source code. The
modules could include data only, routines only, or mixtures of both,
so everything was now treated conceptually at the right level (one
was no longer artificially a subclass of the other). Sequence
association was eliminated, which (along with KINDs) eliminated many
of the problems related to changing precisions when porting codes
from one machine to another. Initial values could be assigned
locally within the module definition itself, eliminating the BLOCK
DATA problems associated with common blocks. And allocatable arrays
could be placed in modules, something that was simply not possible
with static common block storage. And best of all, the compiler can
help the programmer with many aspects of module usage, avoiding all
kinds of mistakes that would have occurred with common blocks where
the user alone, without help from the compiler, is responsible for
consistent usage.

One remaining problem is that I know of no way to avoid module name
conflicts. This occurred sometimes with common block names too, so
this is basically the same problem that remains unsolved. If you
are combining two different codes that happen to have a common
module name, then you must manually go through the codes and rename
one or both of them in order to avoid the conflict. At least with
modules you can use long identifiers to help avoid this issue. With
common blocks in f77 you were limited to six-character names, so it
was not uncommon to have these kinds of conflicts, especially with
library routines that shared data and where the programmer might not
have access to the source code or where the common block name itself
was not documented.

So all in all, while you view the redundant declaration of common
block variables as an advantage, I tend to think of it as several
levels of disadvantages all stacked on top each other.

$.02 -Ron Shepard
Reply With Quote
  #30 (permalink)  
Old 06-02-2012, 04:14 PM
Phillip Helbig---undress to reply
Guest
 
Posts: n/a
Default Re: suggestions for restricted sharing of variables

In article <ron-shepard-47E8E0.11014002062012@news60.forteinc.com>, Ron
Shepard <ron-shepard@NOSPAM.comcast.net> writes:

> > Indeed. What I like about COMMON in this case (otherwise, I want to
> > avoid it and use module variables and will probably do so even here) is
> > that the variables shared between a pair of routines are mentioned there
> > and nowhere else. With module variables, I have to define them outside
> > of these routines.

>
> This redundant declaration of common block variables is actually one
> of the main problems with common blocks.


I agree, hence my proposal for one routine to "USE" what would otherwise
be a local variable in another routine: only declared at one place, and
within the units which use it.

> In f77, there was no way
> other than within the separate routines to declare shared data.
> (Well, okay you could get clever with multiple entry points to some
> extent, but this was rather limited.) It was the responsibility of
> the programmer to ensure that these multiple definitions of the
> common block variables were all consistent. And since the
> individual variables declared within the common block in the
> separate routines could have different names, this was sometimes an
> almost impossible task in practice. With sequence association
> aliasing and mixed real, integer, and double precision variables, it
> was truly a mess, particularly regarding portability on machines
> where you wanted to change precisions and/or data lengths. And
> don't forget that you needed to SAVE these common blocks
> consistently everywhere they were declared, something that most
> programmers did not know and did not do correctly.


I couldn't agree more, which is why I am moving to a non-COMMON
solution, even though I never used any of the ugly tricks you mention
above.

> Many f77 compilers supported the (then) nonstandard INCLUDE
> statement as an extension. This solved some of the problems by
> allowing the common block variables (and the SAVE statement) to be
> declared in one place, and then included into the various routines
> that needed it.


Right, but non-standard.

> From your statement above, you probably would not
> like this approach because it would "require" you to declare the
> common block entities in a separate file.


Right.

> Of course this approach
> also has several of its own problems, besides the fact that it was a
> nonstandard extension, including the reference through a file name
> rather than a global entity. File name conventions are OS dependent
> and are completely outside of the fortran standard, so this approach
> required putting something that was fundamentally nonportable
> directly into your source code. Other problems included conflicts
> between local variable names and these common block variable names
> since there was no way to temporarily rename a common block variable
> on the INCLUDE statement. Combined with the fact that IMPLICIT NONE
> was also nonstandard in f77, this was all just another big mistake
> waiting to happen to the programmer who happened to choose a wrong
> variable name for what he thought was a local variable.


Agreed. Module variables are MUCH better. The ONLY thing I like about
COMMON is the case I'm discussing here (a few out of a large number of
routines need to share a few variables only among themselves).

> You may be too young to have encountered this, but it used to be
> fairly common practice to specify overlay structures for data and
> code in order to reuse as efficiently as possible the limited memory
> that was available to the programmer.


Yes. When I started, typical workstation memory was 16 MB or so, so the
days of using EQUIVALENCE to save RAM (many people probably think that
it's original purpose was for the various tricks for which it has been
abused, rather than to save RAM) or deleting the source code from disk
after compilation were long gone. :-)

> One remaining problem is that I know of no way to avoid module name
> conflicts. This occurred sometimes with common block names too, so
> this is basically the same problem that remains unsolved. If you
> are combining two different codes that happen to have a common
> module name, then you must manually go through the codes and rename
> one or both of them in order to avoid the conflict.


Right.

> At least with
> modules you can use long identifiers to help avoid this issue.


That is what I do. Since my surname is not common among Fortran
programmers, I use it as a prefix. Many publicly available packages
have their own prefix for module names.

> So all in all, while you view the redundant declaration of common
> block variables as an advantage, I tend to think of it as several
> levels of disadvantages all stacked on top each other.


Agreed. I don't view the redundant declaration as an advantage, but
rather the fact that the common block and its variables are mentioned
ONLY within the routines which use them. (Of course, there is nothing
to prevent another routine from having the same declarations.) But
that's the only advantage.

A variant of my proposal could have a special scoping unit within a
routine which is for variables which can be accessed by other routines.

Reply With Quote
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off




All times are GMT. The time now is 02:14 AM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.