For Programmers: Free Programming Magazines  


Home > Archive > Fortran > February 2007 > Passing pointers to derived types to subroutines









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Passing pointers to derived types to subroutines
TobiasH

2007-02-14, 7:07 pm

Hi,
I would like to know why the following code leads to an error (using
Intel Fortran Compiler v9.1):
===========
module MDerivedType
implicit none

type TDerivedType
real, dimension(:,:), pointer :: array => null()
end type
end module MDerivedType

subroutine test(derivedTypePointer)
use MDerivedType
implicit none
type(TDerivedType), pointer, intent(in) :: derivedTypePointer

if (.not. associated(derivedTypePointer%array)) then
print *, "error in test (outside of module)"
return
end if
print *, "test ok"
end subroutine

program PointerProblem
use MDerivedType
implicit none

type(TDerivedType), pointer :: derivedTypePointer => null()
allocate(derivedTypePointer)
allocate(derivedTypePointer%array(2,2))

derivedTypePointer%array = 1.0
call test(derivedTypePointer)
end program PointerProblem
==========
Looking at the disassembly code I encountered, that it is rather the
address of "array" which is passed than a reference of
dericedTypePointer.
Particularly surprising is the fact that the program could easily be
fixed by shifting the subroutine to the module body.
Does anybody has an explanation for this?
Thanks,
Tobias

Arjen Markus

2007-02-14, 7:07 pm

On 14 feb, 15:25, "TobiasH" <tobh...@web.de> wrote:
> Hi,
> I would like to know why the following code leads to an error (using
> Intel Fortran Compiler v9.1):
> ===========
> module MDerivedType
> implicit none
>
> type TDerivedType
> real, dimension(:,:), pointer :: array => null()
> end type
> end module MDerivedType
>
> subroutine test(derivedTypePointer)
> use MDerivedType
> implicit none
> type(TDerivedType), pointer, intent(in) :: derivedTypePointer
>
> if (.not. associated(derivedTypePointer%array)) then
> print *, "error in test (outside of module)"
> return
> end if
> print *, "test ok"
> end subroutine
>
> program PointerProblem
> use MDerivedType
> implicit none
>
> type(TDerivedType), pointer :: derivedTypePointer => null()
> allocate(derivedTypePointer)
> allocate(derivedTypePointer%array(2,2))
>
> derivedTypePointer%array = 1.0
> call test(derivedTypePointer)
> end program PointerProblem
> ==========
> Looking at the disassembly code I encountered, that it is rather the
> address of "array" which is passed than a reference of
> dericedTypePointer.
> Particularly surprising is the fact that the program could easily be
> fixed by shifting the subroutine to the module body.
> Does anybody has an explanation for this?
> Thanks,
> Tobias


The compiler does not "see" the declaration of the "test"
subroutine. Put it in the module MDerivedType or in another
module, make it an internal subroutine to the program or
provide an explicit interface.

Regards,

Arjen

Richard Maine

2007-02-14, 7:07 pm

TobiasH <tobhand@web.de> wrote:

> I would like to know why the following code leads to an error (using
> Intel Fortran Compiler v9.1):

[code elided]
....
> Looking at the disassembly code I encountered, that it is rather the
> address of "array" which is passed than a reference of
> dericedTypePointer.


Good analysis.

> Particularly surprising is the fact that the program could easily be
> fixed by shifting the subroutine to the module body.


And even better analysis. You have found the best solution. All you need
is...

> Does anybody has an explanation for this?


Yes. You have failed to provide an explicit interface for the subroutine
in the main program. Having a pointer dummy argument is one of the many
things that require an explicit interface. It has nothing in particular
to do with being a derived type in this case. It does have to do with
being a pointer.

Putting the subroutine in a module is one way (the best way in most
cases in my opinion) of providing an explicit interface.

Basically, without an explicit interface, the main program has no way of
knowing that the dummy argument is a pointer. Recall that the subroutine
can, in principle, be in a separate file, perhaps not even yet written
when you compile the main program. Recall also that it is perfectly
valid and normal to use a pointer actual argument for a non-pointer
dummy, just like it is valid to use a pointer in most places where you
want its target. Without the explicit interface, that's what the
compiler assumes is going on. That's basically the assumption that the
standard tells the compiler to make. (The standard doesn't say it in
those terms, but that's what it amounts to). So that's exactly what you
are seeing; the target of the pointer get's passed rather than the
pointer itself.

If you want the pointer itself to get passed, the compiler needs to know
about this by having an explicit interface. In the case of a module, the
interface information comes in with the USE statement. That's basicaly
what the USE statement does; it gets the information about things in the
module. In the case of procedures, the information gotten is the
explicit interface.

I recommend making it a habit to put all procedures in modules in new
code. That has many advantages. One of them is that you won't hav eto
keep track of which procedures need explicit interfaces in order to work
correctly. You need an explicit interface for pretty much all the newer
(as of f90) features of the language that have much to do with calling
procedures. The more you use those "new" features, the higher percentage
of your procedures will require explicit interfaces. Pointers are one
such "new" feature.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
TobiasH

2007-02-14, 7:07 pm

What an excellent explanation!
Thank you very much (also to Arjen).

Tobias

gary.l.scott@lmco.com

2007-02-14, 7:07 pm

On Feb 14, 10:58 am, "TobiasH" <tobh...@web.de> wrote:
> What an excellent explanation!
> Thank you very much (also to Arjen).
>
> Tobias


Well, he "wrote the book" so to speak.

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com