Re: Best way to allocate array within subroutine



On Jul 7, 8:05 am, Gordon Sande <g.sa...@xxxxxxxxxxxxxxxx> wrote:
On 2008-07-06 22:27:14 -0300, BenR <Ben.Rup...@xxxxxxxxx> said:



Hello, I have read several posts about this problem in this and other
newsgroups, but I can't quite wrap my head around a solution that fits
my problem.

I have a program with the basic skeleton:
Main Program
Call FileReader(one)
Call FileReader(two)
....
Call FileWriter
End Program

Main Program has 2 allocatable arrays (one and two), the sizes of
which is unknown until they are passed to FileReader.  I need
FileReader to allocate the array "one" and fill it with data, and send
the array back to Main Program.  FileReader will do the same with a
second file and array "two".  From there, Main Program will call
FileWriter using the 2 allocatable arrays.

From what I have read, this operation requires an explicit interface
between Main Program and FileReader.  This can be done by (1) using
"CONTAINS" and putting FileReader in the body of Main Program, (2)
making a module that "CONTAINS" FileReader and USEing it in Main
Program, or (3) using an interface block.

I do not want to use methods (1) or (2) because FileReader is 10 times
the size of Main Program (it was written first as its own program) and
FileReader re-uses variable names that I don't want to get confused
with variables in Main Program.  It is my understanding that anything
that is "CONTAIN"ed in another program block has access to all of the
variables present in the CONTAINer.  This sounds like it could be the
source of a huge debugging headache.  Additionally, in theory, what if
FileReader contained something itself.  I read that something
contained in a module can not contain something itself.

In this case, is an Interface Block the way to go?  Also, could I
declare arrays "one" and "two" as public in a module, and allocate/use
them at will in Main Program and FileReader?  I do not like this
solution because it seems to be the least modular, but if it is
feasible I could make it work with my program structure.

Thanks!
-Ben

Make the main program into a subroutine called "UsedToBeMain". Make a new main
which calls the contained subroutines UsedToBeMain, FileReader and FileWriter.
This new main should have exactly NO variables so the two subrouines will not
have name conflicts. You get explicit interfaces courtesy of the compiler.. So

prog new
implict none
call main
contains
 sub main
 end sub
 sub FR
 end sub
 sub FW
 end sub
end prog

The gotchas are external statements for the now contained units and
the inability to pass the contained units. Neither would seem relevant
from your description. You need to dress up the end statements as well.
Five new lines of code.

You may want to use a POINTER rather than an ALLOCATABLE to allow the
subroutine to do the allocation. This is not a preferred option but
does address limitations of the F90 specification that was later
improved upon for cases like this.

Thanks everyone for the input!
Les, when I said:
Thank you very much for the response. Is adding the FileReader after
a CONTAINS statement in a module functionally the same as adding
FileReader at the end of a program or subroutine?
I was unclear--I should have made the last line read: "the same as
adding a "CONTAINS Filereader" at the end of a program or subroutine",
so I wasn't getting confused with multiple program units within one
file, it was just a typo, sorry.

I think Jugoslav got me straightened out with how CONTAINS works. I
assumed that a subroutine CONTAINED within a module that is used would
have the same behavior as if the subroutine were CONTAINED within the
main program. The scoping and nesting level rules seem to work out
just fine in the end, however.

By the way, can anyone recommend a book that would cover and clarify
all of this information? My Fortran for dummies (well, engineers)
book is more of an "outline and how-to" and less of a "why" kind of
resource. Is the "Fortran 95/2003 Explained" by Metcalf, etc... a
good source?

Thanks,
Ben
.



Relevant Pages