Does the standard address what should happen when the SOURCE in a TRANSFER call
is a derived type with a POINTER component?
In particular, I would like to be certain that if I transfer a structure to an
array of integers, and transfer that back to a variable of the same derived
type, then the pointer will still point to the same target. I don't see anything
in the f95 standard that addresses the transfer of pointers, but I would hope that
it transfers the address or dope vector or whatever the pointer contains, as
opposed to dereferencing the pointer as is done in almost all other contexts.
The closest I can come to guaranteeing this is that (if everything is the right
size) "the value of TRANSFER(TRANSFER(E,D),E) shall be the value of E" but I'm
not sure what "value" means for POINTERS.
The following program illustrates the question:
program test_transfer
implicit none
type mytype
real :: x
real, pointer :: p(:)
integer :: i
end type mytype
real, target :: y(2) = (/5.0,6.0/)
type(mytype) :: t,to
integer :: iol_struct, iol_int, s
integer :: it(12)
t%x = 4.0
t%p => y
t%i = 42
!inquire(iolength=iol_struct) t ! cannot do this because of pointer component
!inquire(iolength=iol_int) it(1)
!print *,"length of structure and integer are ",iol_struct,iol_int
!s = iol_struct/iol_int
s = 12
it(1:s) = transfer(t,0,s)
print *,"transfer result is ",it(1:s)
y(1) = 7.0
to = transfer(it,to)
print *,"transfered back:"
print *," x ",to%x
print *," p ",to%p
print *," i ",to%i
end program
I would expect the output to be something like
transfer result is 1082130432 134519808 -4 2 4 1 42 0 0 0 0 0
transfered back:
x 4.0000000
p 7.0000000 6.0000000
i 42
(Of course the "transfer result" line is processor dependent.)
Of the six Linux f90/f95 compilers, 4 produced the desired result (but one of them
needed the size of 'it' to be 76!), 1 gave "ERROR: Cannot transfer between types
containing arrays or pointers. (Restriction)" and one gave "Illegal use of derived
types in assignment statement" on the "to = transfer..." line. I believe the last
two compilers are, shall we say (to be kind), incomplete, since the standard says
that SOURCE and MOLD may be of any type.
Second question: I cannot use the usual INQUIRE approach to find out how big the
integer array needs to be (see the commented-out code above) because an "output
list item" cannot contain a derived type object that ultimately contains a pointer
component. Are there any other ideas on how to portably determine how big the
array has to be?
For the curious, the point of this exercise is to transfer a structure into an array
of integers which then gets passed to a C function. The C function DOES NOT use it;
it just passes it on to another Fortran subroutine, which will use TRANSFER to
recover the original structure.
Thanks,
Bill
--
William F. Mitchell
Mathematical and Computational Sciences Division
National Institute of Standards and Technology
[log in to unmask] http://math.nist.gov/~mitchell
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|