|
|||
|
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.) |
|
|
||||
|
||||
|
|
|
|||
|
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.) |
|
|||
|
> 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. |
|
|||
|
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 |
|
|||
|
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 |
|
|||
|
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 |
|
|||
|
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". |
|
|||
|
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. |
|
|||
|
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 |
|
|||
|
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. |
|
|||
|
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. |
|
|||
|
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. |
|
|||
|
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 |
|
|||
|
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. |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|