Re: Pointers in derived types, help needed



Saittam <Mattias.Alveteg@xxxxxxxxxxxxxx> wrote:


type A
real,pointer :: var1(:)=>null()
real :: x,y,z,...
end type

type B
type(A),pointer :: var2(:)=>null()
real :: y,...
end type

type(B) :: C,D

Q1) If an argument to a subroutine or function is a pointer then that
subroutine/function must have an explicit interface. So if variable "C"
above is passed as an argument an explicit interface is needed, right?

Wrong for 2 reasons. First, C is not a pointer. The fact that it has a
pointer component is irrelevant. The requirement in question does not
say anything about the argument components; it is about the argument
itself.

Second, you have omitted an essential part of the requiremnt. Even if C
were a pointer, that would not necessarily require an explicit
interface. The requirement in question is on the dummy argument. The
"dummy" part matters - a lot. It is perfectly valid and ordinary to pass
a pointer actual argument to a non-pointer dummy argument. In that case,
the poointer target is what gets associated with the dummy. This is like
most things with pointers - when you refer to the pointer, it is the
same as referring to the target except in cases where you use special
pointer syntax.

Indeed, this explains why an explicit interface is needed for a pointer
dummy. If you look only at the call, not knowing the interface, you
can't tell whether a pointer actual argument is supposed to pass the
pointer itself or the target; it depends on whether the dummy is a
pointer or not. The compiler can't tell either; it needs the explicit
interface to tell it. Lacking an explicit interface, a non-pointer dummy
is assumed.

Of course, I recommend an explicit interface anyway. I recommend
explicit interfaces for everything for new code. Having explicit
interfaces for everything will help avoid several kinds of errors. It
will also keep you from having to bother with all the details of the
exactly cases in which you need them. If you put explicit interfaces
only where they are required, then you have just added a new kind of
error to make.

Note that you do not need to write interface bodies to get explicit
interfaces. On fact, I consider that to be the worse way to do it. You
get explicit interfaces automatically with module procedures adn
internal procedures.

Q2) Since specifying intent for a pointer argument is illegal is
specifying intent for a derived type containing a pointer also illegal

No. Same matter as above. If the standard means a component, it will say
that (or use a more general word like "subobject"). If it doesn't say
that, then it doesn't mean it. The standard at least tries to be precise
about such things. This is far broader than about pointers.

or is the interpretation of

type(B),intent(in) :: CC

that intent(in) is used for the non-pointer bits of CC?

No. That's not true either. You assume they are the opposite. The
working for intent(in) specifically discusses the meaning for pointer
components. It basically forbids you from changing the pointer
association of the component, but places no restriction on the target
(the target is not in general a subobject of the argument in question).

Note, by the way, that f2003 does allow intent for pointer dummy
arguments.

Q3) I hate writing explicit interfaces manually so I usually try
placing my subroutines and functions inside modules,

That is what most people, including myself, recommend.

Since sub3 uses Amod it should be able to safely call sub1 and sub2
even though they have pointer arguments, but can sub2 safely call sub1?
i.e. does the fact that they belong to the same module mean that they
have access to each others interfaces without me typing the interface
explicitly? (I hope so...)

Yes, but...

Your question shows an incorrect assumption. Not only do you not have to
type an interface body, you are not *ALLOWED* to. That is a very
important distinction. If you provide an interface body, you are telling
the compiler that you do *NOT* want the module procedure, but instead
want an external procedure of that name. Since there isn't such an
external procedure, your code won't link. You *NEVER* write an interface
body for a module procedure.

Q4) IF (and only if) sub2 needs an interface to be able to call sub1
safely, how do I write it?

Not applicable. You don't need to an acan't. Note, by the way that the
word "explicit" is actually important. There is always an interface. The
disctinction is in whether it is explicit or is implicitly deduced from
the form of the call.

Q5) Assuming that CC and DD have exactly the same shape, does

CC=DD

mean that pointers in CC point to the same memory as pointers in DD?

Yes.

If so, how do I make sure that *values* are copied to CC rather than
memory addresses?

First, if that's what you want, then you probably don't want pointers at
all. Pointing to the same memory is exactly what one would "expect" if
oen were really using pointers naturally. If you expect or want the
values to be copied, then you probably really want allocatables.
Unfortunately allocatable components are not allowed in f90 or in the
base f95. They are added by the so-called allocatable TR to f95, which
is incorporated as part of the base f2003. If your compiler supports the
allocatable TR, then probably the best thing to do is use allocatables.
They act like you probably intuitively expect. Pointers can be sued to
sort of fake allocatable components, but they have subtle differences in
behavior, including this one.

Otherwise, you could write a defined assignment for the derived type in
question. This posting is a bit long, so I'll not go into that in
detail. Plus, allocatable components are a far cleaner option if your
compiler supports them.

The only reason I use pointers is that not all compilers I use allow
"allocatable" to be used in derived types.

Oh. I didn't read this until writing some of the above. Well, I think
I'll leave it instead of rewriting it all. While that makes sense, it
does handicap you in that

1. You have to be careful to watch for the differences in behavior.
Fortunately, you do seem to be doing that. Asking the question about
assignment shows that you at least understood the possibility of an
issue there. That's one of the big places where the difference shows up.

2. It is generally more error prone. For example, you can easily get
memory leaks or use pointers when they are not defined.

2. A few things are awkward, such as the assignment issue you noted. You
probably do want to define an assignment for the type instead of using
intrinsic assignment. Inside that intrinsic assignment, you'll need to
allocate the new pointers. Also be aware that assignment is tricky to do
without causing memory leaks.

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



Relevant Pages

  • Re: Why ABCs make bad Interfaces
    ... > equivalent to an Abstract Base Class (ABC). ... > because it is common practice to implement an interface using ABC's. ... To convert an object to its interface, you return a fat pointer ... The NaiveInt constructor has to set up the vtables, ...
    (comp.object)
  • Re: another COM-Question: how to inject a type-lib into a dll?
    ... > But let me ask just another question on this: If this pointer is ... This is why the object exposes the COM interface in the first ... Make sure SomeObject has a reference count of 1 at this point. ... The declaraion of SomeOtherCOMMethod has a different signature. ...
    (microsoft.public.vc.atl)
  • Re: Stupid tcl/tcom newbie question
    ... Pointer to variant in tcom ... Excel's COM interface does not appear to have any methods ... So I can't test my code on Excel. ... Sub Load DLLComp() ...
    (comp.lang.tcl)
  • Re: RPC_E_WRONG_THREAD on accessing interface pointer from GIT
    ... The thread that gets the interface (allow me to call it ... IObjectInterface pointer is retrieved from the GIT from another COM ... successfully retrieve the pointer to the other object from the GIT, ...
    (microsoft.public.win32.programmer.ole)
  • Re: MODULEand USE versus Argument Passing
    ... Suppose I am using one of the NAG routines, e.g. d01akf, to ... | such that one could pass a structure pointer through to the called ... with datatypes by means of suppressing explicit interface, ...
    (comp.lang.fortran)