Thanks, Malcolm!
Malcolm Cohen wrote:
>
> William F Mitchell asked:
> >Does the standard address what should happen when the SOURCE in a TRANSFER
> >call is a derived type with a POINTER component?
>
> Not really, though the intent is (I think) as you describe.
>
> In general though, I'd advise against using TRANSFER unless you really need it.
> That doesn't seem to be the case here.
> TRANSFER does tend to confuse both users and implementors. It also doesn't
> tend to be particularly efficient.
Yes, I find it somewhat confusing, and have managed to avoid it until now. But
I think I do need to use it now. As always, the real case is more complicated
than the illustration in the question. (See below)
>
> >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?
>
> Note that INQUIRE does not give you any useful information about the array size
> needed for TRANSFER, except by accident. It gives you the values for RECL=.
Yes I realize the standard doesn't guarantee that, and have seen discussions on
this here before. But I had the impression that that accident was pretty universal,
and that I wouldn't get into trouble until long after I'd forgotten what I did or
until someone else uses my code :-)
> You wrote:
> >s = 12
> >it(1:s) = transfer(t,0,s)
>
> Instead, do
>
> S = SIZE(TRANSFER(T,IT))
> IT(:S) = TRANSFER(T,IT)
Of course ... much better. Thanks! For some reason I was thinking that
TRANSFER(T,IT) would have the size of IT, but looking back at the definition
again I see it has the correct size. As you said, TRANSFER tends to confuse.
> >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.
>
> Well, this does more than that - it makes a "copy" of the derived type.
> I don't know whether you *want* that - maybe you do?
Yes, I do.
> If you just want to pass the derived type argument through, you can probably
> just pass the variable itself (receiving it into a C "void *" pointer). That
> works with all the compilers I'm familiar enough with, including our own - we
> don't do anything funky with derived type arguments.
OK, here's the real story. In this C library (which is still under development)
for which I am responsible for the Fortran interface, there is a user defined
type for IDs (identifiers for grid elements -- think FEM). In C, might be an integer,
might be a pointer, might be a structure, might be something else -- you just don't know.
The user will define it later. In Fortran, it is either an integer or type(LB_ID).
The argument that is passed to the library functions is an _array_ of IDs. Under this
scheme, just passing the argument, as you say, works with every compiler I've tried.
The problem with this scheme is that the user defined type has to be known when the
library is built, so essentially you have to have a different compilation of the
library for every application program. So now there is a design change proposed
in which an ID is an array of integers, with the application code responsible for
converting what it uses for IDs to the array of integers. The original question
came from supposing the ID is a structure containing a pointer. So I believe I
need to use TRANSFER to create the array of integers, and I need to copy it to create
an array of IDs, actually a rank 2 array of size (size(transfer(t,it)),num_elements),
for the actual argument.
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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|