Re: Pointers in derived types, help needed
- From: nospam@xxxxxxxxxxxxx (Richard Maine)
- Date: Sun, 8 Oct 2006 10:40:20 -0700
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
.
- Follow-Ups:
- Re: Pointers in derived types, help needed
- From: Saittam
- Re: Pointers in derived types, help needed
- References:
- Pointers in derived types, help needed
- From: Saittam
- Pointers in derived types, help needed
- Prev by Date: Re: Pointers in derived types, help needed
- Next by Date: Re: Pointers in derived types, help needed
- Previous by thread: Re: Pointers in derived types, help needed
- Next by thread: Re: Pointers in derived types, help needed
- Index(es):
Relevant Pages
|
|