Re: Double precision arrays and subroutines
- From: Gordon Sande <g.sande@xxxxxxxxxxxxxxxx>
- Date: Thu, 12 Apr 2007 20:16:33 GMT
On 2007-04-12 16:40:20 -0300, Brooks Moses <bmoses-nospam@xxxxxxxxxxxxxxxxxx> said:
Shug Boabby wrote:After some processing, it then calls a subroutine
call av (nx, workd(ipntr(1)), workd(ipntr(2)))
I looked at the definition for av, expecting it to require an integer
and two doubles. However, the first few lines of av are
subroutine av (nx, v, w)
integer nx
Double precision v(nx*nx), w(nx*nx)
which I believe means that it is expecting an integer and two double
arrays.
My only explanation would be that workd(ipntr(1)) is sending a pointer
to this element in the array, and then av is considering that pointer
to be the start of an nx * nx array.
Clarifications would be greatly appreciated.
To add to what other people have said: Yes, that's essentially what's happening, but it's not legal Fortran code.
What happens is that, in Fortran, these two program units are independent. The subroutine and the program that calls it are compiled separately, and normally the compiler doesn't know about one when it's compiling the other. Although they're usually in the same source file, it's useful to imagine that they're in separate files being compiled at separate times and then linked together.
Thus, the compiler doesn't know about the mismatch between the fact that the subroutine call is being given an integer and two scalar doubles, and the subroutine declaration is expecting an integer and two double arrays. It compiles the subroutine call to pass along scalar doubles, and it compiles the subroutine to expect double arrays.
This sort of thing is, in most cases, called a "bug".
It is only a "bug" when there is a type mismatch. Passing an array element to
provide an offset into an array is legal and common in much older code. It
is called an array slice in modern terminology if one is willing to overlook
some tecnical issues.
Separate compilation is used to cheat on type mismatchs for a common form
of "dynamic" allocation from the bad old days before dynamic allocation
came to Fortran.
This is the feature of Fortran that leads many to make the claim that
Fortran uses pass by reference semantics. It has too many problems to
be a useful summary even if it captures some of the spirit of passing
an array element to an array.
Since the original question was about some legacy code it is quite likely
that the old style do it yourself storeage allocation was in use. Complete
with deliberate type mismatch.
In this case, however, it seems that the way that this Fortran compiler works is that on the machine-code level it doesn't actually pass the values; it passes their location in memory -- that is, a "pointer" in the C-language sense of the word. And so, for that particular compiler, this piece of code happens to work right.
Other compilers do things like passing the size of an array along with its location in memory, and thus on those compilers this code will fail in ugly and difficult-to-debug ways. But apparently this program was never (we hope!) run on such a compiler....
More likely when using assumed shape which is a Fortran 90 notion.
- Brooks
P.S. Note that, in more recent versions of Fortran, there are much better ways to write this code -- both to allow the compiler to check and make sure the subroutine does match the subroutine call, and to pass sections of arrays to subroutines. Please don't judge modern Fortran by this historical ugliness! :)
.
- References:
- Double precision arrays and subroutines
- From: Shug Boabby
- Re: Double precision arrays and subroutines
- From: Brooks Moses
- Double precision arrays and subroutines
- Prev by Date: Re: Double precision arrays and subroutines
- Next by Date: OT: Understand for Fortran
- Previous by thread: Re: Double precision arrays and subroutines
- Next by thread: Re: Double precision arrays and subroutines
- Index(es):
Relevant Pages
|