Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

is allocated memory deallocated once the pointer goes out of scope?

192 views
Skip to first unread message

Nicolas Bock

unread,
May 3, 2013, 6:51:05 PM5/3/13
to
Hi,

Suppose I have this subroutine:

subroutine a ()
integer, pointer :: b
allocate(b)
end subroutine a

The variable b is on the subroutine's stack and will therefore get destroyed once the program returns from the subroutine. But what about the target it was pointing to? As far as I can tell from reading the F90 standard, the target is _not_ deallocated, but I can't find a definite statement saying that explicitly.

Thanks already,

nick

glen herrmannsfeldt

unread,
May 3, 2013, 8:07:30 PM5/3/13
to
Use ALLOCATABLE if you want the system to deallocate them for you.

The standard probably doesn't tell you what compilers don't have to
do, only what they do have to do.

Note that, other than running out of memory, there is no way for a
program to tell that the target was or wasn't deallocated.
(On a garbage collection system, it likely would be. Fortran allows
for that, but doesn't require it.)

There is pretty much nothing in the standard that tells you that
a program will or won't run out of memory. That is part of the
"system dependencies,"

Many systems now use "allocate on write." There is one page filled
with zeros, which is mapped into all the allocated memory, and marked
read only. When you actually write to the page, the system maps an
available page and allows write.

Note that your program never writes to the allocated array.

So, not only does the standard not say that it will or won't be
deallocated, it might not even be actually allocated. Your program
won't be able to tell either way.

-- glen

Richard Maine

unread,
May 3, 2013, 10:49:16 PM5/3/13
to
As Glen notes, the standard is silent on this, and intentionally so.
That would be what is usually known as garbage collection. The standard
neither mandates nor prohibits compilers from doing garbage collection.
I think that most compilers don't, although there are at least some
compilers that have garbage collection as an option.

In addition to what Glen said, I'll note that if there end up being
other pointers to that same target, and those other pointers are local
to the subroutine, then that's a completely different matter. I wonder
whether that might actually be your question, because, as Glen noted,
the deallocation doesn't otherwise matter in ways directly visible to
Fortran. It is fairly common for people to try to simplify their
question to something that they think is equivalent, but unfortunately
is not so. In the case where there are other non-local (or SAVEd local)
pointers to the same target, the standard does cover it and says that
the target is not deallocated. Only if *ALL* pointers to the target go
away is there the possibility of garbage collection.

It would actually be a bit of work to cite the parts of the standard
that say the target remains as long as there are still pointers to it.
That's because the most important parts are omissions, which tend to be
hard to cite concisely. In particular, the standard lists ways in which
things can become undefined, and this is not in those lists, so those
other pointers would not become undefined.

--
Richard Maine
email: last name at domain . net
domain: summer-triangle

glen herrmannsfeldt

unread,
May 4, 2013, 2:22:45 PM5/4/13
to
Richard Maine <nos...@see.signature> wrote:
> Nicolas Bock <nicol...@gmail.com> wrote:

(snip)
>> subroutine a ()
>> integer, pointer :: b
>> allocate(b)
>> end subroutine a

>> The variable b is on the subroutine's stack and will therefore get
>> destroyed once the program returns from the subroutine. But what about
>> the target it was pointing to? As far as I can tell from reading the F90
>> standard, the target is _not_ deallocated, but I can't find a definite
>> statement saying that explicitly.

One that I didn't mention before is that there is no requirement for
b to be on a stack, or to go away when the subroutine returns.
The compiler is allowed to implement it using static storage, but
you are not allowed to test to see if it is in fact still allocated
on a subsequent call.

> As Glen notes, the standard is silent on this, and intentionally so.
> That would be what is usually known as garbage collection. The standard
> neither mandates nor prohibits compilers from doing garbage collection.
> I think that most compilers don't, although there are at least some
> compilers that have garbage collection as an option.

I wondered some time ago about the possibility of a Fortran compiler
generating JVM code as output. (That is, the Java Virtual Machine.)
In that case, it would naturally use garbage collection.

> In addition to what Glen said, I'll note that if there end up being
> other pointers to that same target, and those other pointers are local
> to the subroutine, then that's a completely different matter. I wonder
> whether that might actually be your question, because, as Glen noted,
> the deallocation doesn't otherwise matter in ways directly visible to
> Fortran. It is fairly common for people to try to simplify their
> question to something that they think is equivalent, but unfortunately
> is not so. In the case where there are other non-local (or SAVEd local)
> pointers to the same target, the standard does cover it and says that
> the target is not deallocated. Only if *ALL* pointers to the target go
> away is there the possibility of garbage collection.

Even more, in the case in question, the allocation doesn't matter
either. A good compiler might notice and not actuall allocate.
More likely, as I noted, the OS might figure it out.

> It would actually be a bit of work to cite the parts of the standard
> that say the target remains as long as there are still pointers to it.
> That's because the most important parts are omissions, which tend to be
> hard to cite concisely. In particular, the standard lists ways in which
> things can become undefined, and this is not in those lists, so those
> other pointers would not become undefined.

The interesting case for garbage collection is the circularly linked
list. In that case, there are pointers to everthing, but if there are no
other pointers, it still can't be referenced, and should be GCed.
If there is any question about it, one should break one of the links.

-- glen

Nicolas Bock

unread,
May 6, 2013, 1:12:17 PM5/6/13
to
Sorry for the strange extra line in the quoted email. Google's groups web interface seems to have added those, for clarify I am sure.

You are right, what I was really interested in is better described with this code:

function bla ()
integer, pointer :: bla
allocate(bla)
end function bla

integer, pointer :: a

a => bla()

What I am concerned about is whether a will point to allocated memory. If bla() deallocated the memory it allocated, then obviously this program would behave in an undefined way. But from your answers I gather that it would be running just fine, since a will point to the memory allocated in bla().

Richard Maine

unread,
May 6, 2013, 3:22:21 PM5/6/13
to
Nicolas Bock <nicol...@gmail.com> wrote:

> On Friday, May 3, 2013 8:49:16 PM UTC-6, Richard Maine wrote:

> > In the case where there are other non-local (or SAVEd local)
> > pointers to the same target, the standard does cover it and says that
> > the target is not deallocated. Only if *ALL* pointers to the target go
> > away is there the possibility of garbage collection.
> >
...
> You are right, what I was really interested in is better described with
this code:
>
> function bla ()
> integer, pointer :: bla
> allocate(bla)
> end function bla
>
> integer, pointer :: a
>
> a => bla()
>
> What I am concerned about is whether a will point to allocated memory. If
> bla() deallocated the memory it allocated, then obviously this program
> would behave in an undefined way. But from your answers I gather that it
> would be running just fine, since a will point to the memory allocated
> in bla().

Correct. That code is fine (assuming an explicit interface for bla, as
is required).

Now my personal recommendation is to assiduously avoid ever using
functions that return pointers. I am quite serious about wishing that
they had not even been introduced into the standard. Use a subroutine
and pass the pointer back via an argument instead. Functions that return
pointers are *EXTREMELY* error prone. Even experts mess them up at
times. I find it instructive that there was at least one case of someone
here posting an example of such a function that he considered a "safe"
kind of use, but actually had one of the common errors because he was
concentrating on other aspects and missed that error. He even knew
better than that error, but it is an easy one to make anyway.
Unfortunately, some of the common errors are of types that do not tend
to get caught at compile time, but instead cause confusing run-time
behavior.

Try, for a common example, typoing "=" instead of "=>". The code will
still compile and run (given a few contextual assumptions that are often
true). It just won't do anything particularly cose to what was expected.

Anyway... yes, the standard says (in a roundabout way, but it does say
it) that your code shown is ok. I personally, however, recommend against
it.

glen herrmannsfeldt

unread,
May 6, 2013, 3:26:35 PM5/6/13
to
Nicolas Bock <nicol...@gmail.com> wrote:
> On Friday, May 3, 2013 8:49:16 PM UTC-6, Richard Maine wrote:

(snip)

> Sorry for the strange extra line in the quoted email.
> Google's groups web interface seems to have added those,
> for clarify I am sure.

> You are right, what I was really interested in is better
> described with this code:

> function bla ()
> integer, pointer :: bla
> allocate(bla)
> end function bla

> integer, pointer :: a
> a => bla()

> What I am concerned about is whether a will point to
> allocated memory. If bla() deallocated the memory it allocated,
> then obviously this program would behave in an undefined way.
> But from your answers I gather that it would be running just
> fine, since a will point to the memory allocated in bla().

Yes, you should be fine. One that is known to cause problems is
functions returning pointers to local variables or local allocatables.

I believe, for example, that you would NOT want to:

function bla ()
integer, pointer :: bla
integer, allocatable, target :: this
allocate(this)
bla => this
end function bla

I believe in this case, the allocated data is deallocated in return.
On the other hand, you could:

function bla ()
integer, pointer :: bla
integer, allocatable, target, save :: this
allocate(this)
bla => this
end function bla

In which case it should NOT be deallocated, but you can only
call it once.

(I didn't try compiling either of them, though.)

-- glen

glen herrmannsfeldt

unread,
May 6, 2013, 4:27:43 PM5/6/13
to
Richard Maine <nos...@see.signature> wrote:
> Nicolas Bock <nicol...@gmail.com> wrote:

(snip)

>> function bla ()
>> integer, pointer :: bla
>> allocate(bla)
>> end function bla

>> integer, pointer :: a
>> a => bla()

(snip)

> Correct. That code is fine (assuming an explicit interface for bla,
> as is required).

> Now my personal recommendation is to assiduously avoid ever using
> functions that return pointers. I am quite serious about wishing
> that they had not even been introduced into the standard.
> Use a subroutine and pass the pointer back via an argument instead.
> Functions that return pointers are *EXTREMELY* error prone.
> Even experts mess them up at times.

Yes.

Well, in general it isn't functions returning pointers that are
a problem, but functions returning the only copy of a pointer,
as in the case shown. Specifically, when it is expected that someone
get around to deallocating it. Even C programmers don't like it.

(One result is that there are C library routines that return pointers
to static data. Very confusing if you aren't careful with them.

-- glen

glen herrmannsfeldt

unread,
May 6, 2013, 4:48:04 PM5/6/13
to
(snip, I wrote)
> I believe, for example, that you would NOT want to:

> function bla ()
> integer, pointer :: bla
> integer, allocatable, target :: this
> allocate(this)
> bla => this
> end function bla

> I believe in this case, the allocated data is deallocated in return.
> On the other hand, you could:

> function bla ()
> integer, pointer :: bla
> integer, allocatable, target, save :: this
> allocate(this)
> bla => this
> end function bla

(snip)
> (I didn't try compiling either of them, though.)

It seems that gfortran will compile these for arrays, but not scalars.
I didn't try running them to see if they fail.

-- glen

Richard Maine

unread,
May 6, 2013, 4:58:14 PM5/6/13
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Richard Maine <nos...@see.signature> wrote:

> > Now my personal recommendation is to assiduously avoid ever using
> > functions that return pointers. I am quite serious about wishing
> > that they had not even been introduced into the standard.
> > Use a subroutine and pass the pointer back via an argument instead.
> > Functions that return pointers are *EXTREMELY* error prone.
> > Even experts mess them up at times.
>
> Yes.
>
> Well, in general it isn't functions returning pointers that are
> a problem, but functions returning the only copy of a pointer,

which is exactly the distinction that a previous poster was trying to
make when he managed to illustrate that his example of a "safe" case had
an error. I'd say that, just like that poster, you are concentrating on
a particular kind of error, but overlooking others. The "=" instead of
"=>" error comes up regardless of what the pointer's target is. I
personally continue to maintain that functions returning pointers are
inherently a problem in Fortran - in *ALL* cases.

Even if we ignore issues such as the above-mentioned typo, I would
maintain that needing to keep in mind the distinctions between the
various cases is a problem in itself. So no, you (or anyone else) is not
going to be able to come up with an example that I think is ok, because
having to evaluate whether it is ok is already a problem in my mind. I'm
a big fan on simplicity in some things, including this one. Sure, there
are places where simple just won't work (insert the quote usually,
although questionably, attributed to Einstein). But a simple rule works
fine here. "Don't use functions that return pointers" is a simple rule -
and that's the one I advocate.

As mentioned above, I seriously wish that the langauge didn't allow such
functions at all. That would have made my rule even simpler to follow in
that compilers would enforce it.

Richard Maine

unread,
May 6, 2013, 5:07:09 PM5/6/13
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> It seems that gfortran will compile these for arrays, but not scalars.
> I didn't try running them to see if they fail.

Allocatable scalars are an f2003 feature. Alas, they are one of the
f2003 features that has been pretty slow about getting implemented.

I recall that the failure of compilers to implement allocatable scalars
pretty quickly derailed some of my earliest attempts to experiment with
using f2003's object-oriented features. A polymorphic variable has to be
either allocatable or a pointer (or a dummy argument, but that just puts
off the question). Making them all pointers gives up a lot of the
advantages.

And without allocatable scalars, allocatable character length is all but
useless.

glen herrmannsfeldt

unread,
May 7, 2013, 2:00:27 AM5/7/13
to
Richard Maine <nos...@see.signature> wrote:

(snip)
>> > Now my personal recommendation is to assiduously avoid ever using
>> > functions that return pointers. I am quite serious about wishing
>> > that they had not even been introduced into the standard.
>> > Use a subroutine and pass the pointer back via an argument instead.
>> > Functions that return pointers are *EXTREMELY* error prone.
>> > Even experts mess them up at times.

(snip)
>> Well, in general it isn't functions returning pointers that are
>> a problem, but functions returning the only copy of a pointer,

> which is exactly the distinction that a previous poster was trying to
> make when he managed to illustrate that his example of a "safe" case had
> an error. I'd say that, just like that poster, you are concentrating on
> a particular kind of error, but overlooking others. The "=" instead of
> "=>" error comes up regardless of what the pointer's target is. I
> personally continue to maintain that functions returning pointers are
> inherently a problem in Fortran - in *ALL* cases.

Yes, probably especially among C programmers not used to =>.

But OK, I am not against subroutines instead of functions.
Especially since you can't subscript or extract structure members
from function values.

I have done in Java:

((int[])hashtable.get(key))[0];

but you can't do that the same way in Fortran.

> Even if we ignore issues such as the above-mentioned typo, I would
> maintain that needing to keep in mind the distinctions between the
> various cases is a problem in itself. So no, you (or anyone else)
> is not going to be able to come up with an example that I think
> is ok, because having to evaluate whether it is ok is already
> a problem in my mind.

> I'm a big fan on simplicity in some things, including this one.
> Sure, there are places where simple just won't work (insert the
> quote usually, although questionably, attributed to Einstein).
> But a simple rule works fine here. "Don't use functions that
> return pointers" is a simple rule - and that's the one I advocate.

> As mentioned above, I seriously wish that the langauge didn't allow
> such functions at all. That would have made my rule even simpler
> to follow in that compilers would enforce it.

I suppose, but overall I am against enforcing good programming
practices through language rules. Orthogonality makes it easier
to remember how things work without having to look up all the
exceptions.

-- glen

Janus Weil

unread,
May 7, 2013, 2:39:48 AM5/7/13
to

> > It seems that gfortran will compile these for arrays, but not scalars.
> > I didn't try running them to see if they fail.
>
> Allocatable scalars are an f2003 feature. Alas, they are one of the
> f2003 features that has been pretty slow about getting implemented.

Actually gfortran has been supporting allocatable scalar for some time now (which does not mean that there can not be bugs, of course).

The examples seem to compile with gfortan 4.7 at least. Which version did you use?

Cheers,
Janus

glen herrmannsfeldt

unread,
May 7, 2013, 4:21:21 AM5/7/13
to
Janus Weil <ja...@gcc.gnu.org> wrote:

(snip, I wrote)
>> > It seems that gfortran will compile these for arrays, but
>> > not scalars. I didn't try running them to see if they fail.

(snip)
> Actually gfortran has been supporting allocatable scalar for some
> time now (which does not mean that there can not be bugs, of course).

> The examples seem to compile with gfortan 4.7 at least.
> Which version did you use?

It seems to be 4.4.5. It isn't my computer, though.

-- glen

Janus Weil

unread,
May 7, 2013, 4:40:24 AM5/7/13
to

> >> > It seems that gfortran will compile these for arrays, but
> >> > not scalars. I didn't try running them to see if they fail.
>
> (snip)
>
> > Actually gfortran has been supporting allocatable scalar for some
> > time now (which does not mean that there can not be bugs, of course).
> >
> > The examples seem to compile with gfortan 4.7 at least.
> > Which version did you use?
>
> It seems to be 4.4.5. It isn't my computer, though.

Well, yeah. Allocatable scalars have only been implemented for 4.5.0 (which is three years old by now), as documented in http://gcc.gnu.org/wiki/Fortran2003Status.

And to reply to Richard's comment: Yes, the main motivation to implement allocatable scalars was indeed their usefulness for OOP (which was also introduced in gfortran 4.5, but was still very experimental at that stage).

Cheers,
Janus

Wolfgang Kilian

unread,
May 7, 2013, 4:42:17 AM5/7/13
to
On 05/07/2013 08:00 AM, glen herrmannsfeldt wrote:
> Richard Maine <nos...@see.signature> wrote:
>
> (snip)
>>>> Now my personal recommendation is to assiduously avoid ever using
>>>> functions that return pointers. I am quite serious about wishing
>>>> that they had not even been introduced into the standard.
>>>> Use a subroutine and pass the pointer back via an argument instead.
>>>> Functions that return pointers are *EXTREMELY* error prone.
>>>> Even experts mess them up at times.
>
> (snip)
>>> Well, in general it isn't functions returning pointers that are
>>> a problem, but functions returning the only copy of a pointer,
>
>> which is exactly the distinction that a previous poster was trying to
>> make when he managed to illustrate that his example of a "safe" case had
>> an error. I'd say that, just like that poster, you are concentrating on
>> a particular kind of error, but overlooking others. The "=" instead of
>> "=>" error comes up regardless of what the pointer's target is. I
>> personally continue to maintain that functions returning pointers are
>> inherently a problem in Fortran - in *ALL* cases.
>
> Yes, probably especially among C programmers not used to =>.

> But OK, I am not against subroutines instead of functions.
> Especially since you can't subscript or extract structure members
> from function values.

Sometimes it's tradeoff between code safety and clarity.

For a subroutine, if I just have the call, I don't know the INTENT of an
argument. For that, I must look up the subroutine definition or
interface. On the other hand, the intent of a function result, and thus
the flow of data, is evident from the calling syntax.

Furthermore, one can't use a subroutine argument as the argument to
another procedure without introducing a variable in the caller's scope.
While avoiding the pitfalls of pointer functions, one introduces some
overhead on the caller's side. Consider

call do_something (..., abc%f, ...)

which you may later want to change into

call do_something (..., abc%get_f_ptr (), ...)

(using a pointer if 'f' is large so you don't get a temporary copy).
The alternative may look like

class(foo), dimension(:,:), pointer :: f
...
...
call abc%get_f_ptr (f)
call do_something (a, b, f)

In the one-line implementation, neither the type nor the shape of 'f'
need to be known to the caller, and the code change is local. (Type
and shape is known to the compiler without declaring it in the caller
module. The type of 'f' need not be accessible by a USE directive.)

In both cases, 'abc' must have a TARGET attribute, but the compiler
probably won't tell you. In my experience, this is easy to forget and a
more annoying source of error in the context of pointers than the
presence of functions.

>> [...]
> I suppose, but overall I am against enforcing good programming
> practices through language rules. Orthogonality makes it easier
> to remember how things work without having to look up all the
> exceptions.

Agreed.

-- Wolfgang

>
> -- glen
>


--
E-mail: firstnameini...@domain.de
Domain: yahoo

Nicolas Bock

unread,
May 7, 2013, 4:23:24 PM5/7/13
to
On Monday, May 6, 2013 2:27:43 PM UTC-6, glen herrmannsfeldt wrote:
> Richard Maine <nos...@see.signature> wrote:
>
> Well, in general it isn't functions returning pointers that are
> a problem, but functions returning the only copy of a pointer,
> as in the case shown. Specifically, when it is expected that someone
> get around to deallocating it. Even C programmers don't like it.

In my experience functions returning a pointer is a fairly common design pattern in C though. Just take the malloc() interface for example. Or the factory method pattern in C libraries such as glib. I am not trying to say that this means that such patterns are good and safe to use, but as a C programmer one cannot avoid using such patterns it seems.

Nicolas Bock

unread,
May 7, 2013, 4:24:35 PM5/7/13
to
On Monday, May 6, 2013 1:22:21 PM UTC-6, Richard Maine wrote:
>
> Try, for a common example, typoing "=" instead of "=>". The code will
> still compile and run (given a few contextual assumptions that are often
> true). It just won't do anything particularly cose to what was expected.

Just out of curiosity: What does "=" mean in this context?

Richard Maine

unread,
May 7, 2013, 4:30:25 PM5/7/13
to
It means to copy the value from the right-hand-side pointer's target and
assign that value to the target of the pointer on the left-hand side. It
is just plain old ordinary assignment having nothing in particular to do
with pointers. Any pointers in sight are dereferenced to be their
targets.

Nicolas Bock

unread,
May 7, 2013, 4:32:36 PM5/7/13
to
On Tuesday, May 7, 2013 2:30:25 PM UTC-6, Richard Maine wrote:
> Nicolas Bock <nicol...@gmail.com> wrote:
>
> > Just out of curiosity: What does "=" mean in this context?
>
> It means to copy the value from the right-hand-side pointer's target and
> assign that value to the target of the pointer on the left-hand side. It
> is just plain old ordinary assignment having nothing in particular to do
> with pointers. Any pointers in sight are dereferenced to be their
> targets.

So it's a "deep copy" as a python programmer would call it?

glen herrmannsfeldt

unread,
May 7, 2013, 5:34:22 PM5/7/13
to
Wolfgang Kilian <kil...@invalid.com> wrote:

(snip, Richard wrote)
>>> which is exactly the distinction that a previous poster was trying to
>>> make when he managed to illustrate that his example of a "safe" case had
>>> an error. I'd say that, just like that poster, you are concentrating on
>>> a particular kind of error, but overlooking others. The "=" instead of
>>> "=>" error comes up regardless of what the pointer's target is. I
>>> personally continue to maintain that functions returning pointers are
>>> inherently a problem in Fortran - in *ALL* cases.

(snip, then I wrote)
>> Yes, probably especially among C programmers not used to =>.

>> But OK, I am not against subroutines instead of functions.
>> Especially since you can't subscript or extract structure members
>> from function values.

> Sometimes it's tradeoff between code safety and clarity.

> For a subroutine, if I just have the call, I don't know the INTENT
> of an argument. For that, I must look up the subroutine
> definition or interface. On the other hand, the intent of a
> function result, and thus > the flow of data, is evident from
> the calling syntax.

I suppose, but you might have a convention where INTENT(OUT)
arguments come first, and others later.

> Furthermore, one can't use a subroutine argument as the argument to
> another procedure without introducing a variable in the caller's scope.

Yes, but often enough you need a variable anyway.

I will have to see sometime what OO Fortran looks like.
In Java, it isn't too unusual to have a method return an object
reference that you immediately use for the next method. That is,
in the form:

method1(args1).method2(args2).method3(args3).method4();

Not having actually tried it, as far as I know you can't do
that in Fortran without an extra variable at each level.

> While avoiding the pitfalls of pointer functions, one introduces
> some overhead on the caller's side. Consider

> call do_something (..., abc%f, ...)

> which you may later want to change into

> call do_something (..., abc%get_f_ptr (), ...)

> (using a pointer if 'f' is large so you don't get a temporary copy).

Yes. Well, there are some cases where returning a pointer to an
array is a much better choice than returning the whole array.

Note that you can't subscript functions returning arrays, but it
would be wasteful if you could. It shouldn't be so bad to subscript
an array pointer, but you still can't do it.

-- glen

Richard Maine

unread,
May 7, 2013, 6:14:19 PM5/7/13
to
Perhaps. I don't really do python, so I can't say anything about that.
Yes, I think that might sometimes be called a deep copy. But I'm not
sure that is completely accurate in all cases. It isn't the terminology
I'd use here. Among other things, that terminology seems limitted to
copying (aka assignment), but the principles involved in Fortran are not
specific to assignment. "Deep copy" doesn't seem likely to help you
understand the general evaluation of expressions that involve pointers
but do not involve assignment. (Expressions get used in many places
other than just assignment).

I think that the best way to think about Fortran pointers is to almost
forget the word "pointer". That word leads to multiple confusions. I'm
not at all sure that pointers in some other languages make a very good
analogy at all.

Although it is not the terminology used by the Fortran standard, I
prefer to think of a Fortran pointer as an alias. That is, it is an
alternate name that can be used to refer to some other variable (the
target). I might also note that a Fortran pointer is *VERY* simillar to
a dummy argument in this regard. In most contexts, a pointer acts just
as though you had used the target directly. Another way of describing
this is that pointers are automatically dereferenced. You don't do
anything like the c "^" to dereference the pointer; just using the
pointer name as is already implies dereferencing.

It is when you do *NOT* want to dereference the pointer that you have to
do something special in Fortran. Usually that "something special" is a
separate statement that is particular to pointers. In the case of
assignment, you use the pointer assignment statement ("=>") instead of
regular assignment. Other cases are the nullify, deallocate, and
allocate statements. There is perhaps a presumption that there are more
cases of wanting to dereference the pointer than of setting up what it
refers to.

I am told (if I recall correctly) that Fortran pointers are somewhat
like Java reference variables, but I haven't used Java at all and I
could easily have that confused (or have been told inaccurately).

glen herrmannsfeldt

unread,
May 7, 2013, 8:13:38 PM5/7/13
to
Richard Maine <nos...@see.signature> wrote:
> Nicolas Bock <nicol...@gmail.com> wrote:

(snip regarding = and pointers)

>> So it's a "deep copy" as a python programmer would call it?

> Perhaps. I don't really do python, so I can't say anything about that.

Hmm. To be deep copy, it should recursively assign.
I am not sure about that one.

If you have a structure containing pointers to to structures
containing pointers containing ... and assign one, what does it do?

> Yes, I think that might sometimes be called a deep copy. But I'm not
> sure that is completely accurate in all cases. It isn't the terminology
> I'd use here. Among other things, that terminology seems limitted to
> copying (aka assignment), but the principles involved in Fortran are not
> specific to assignment. "Deep copy" doesn't seem likely to help you
> understand the general evaluation of expressions that involve pointers
> but do not involve assignment. (Expressions get used in many places
> other than just assignment).

> I think that the best way to think about Fortran pointers is to almost
> forget the word "pointer". That word leads to multiple confusions. I'm
> not at all sure that pointers in some other languages make a very good
> analogy at all.

> Although it is not the terminology used by the Fortran standard, I
> prefer to think of a Fortran pointer as an alias. That is, it is an
> alternate name that can be used to refer to some other variable (the
> target). I might also note that a Fortran pointer is *VERY* simillar to
> a dummy argument in this regard. In most contexts, a pointer acts just
> as though you had used the target directly. Another way of describing
> this is that pointers are automatically dereferenced. You don't do
> anything like the c "^" to dereference the pointer; just using the
> pointer name as is already implies dereferencing.

You mean *. (I haven't done Pascal for a while, it might be ^ there.)

> It is when you do *NOT* want to dereference the pointer that you have to
> do something special in Fortran. Usually that "something special" is a
> separate statement that is particular to pointers. In the case of
> assignment, you use the pointer assignment statement ("=>") instead of
> regular assignment. Other cases are the nullify, deallocate, and
> allocate statements. There is perhaps a presumption that there are more
> cases of wanting to dereference the pointer than of setting up what it
> refers to.

> I am told (if I recall correctly) that Fortran pointers are somewhat
> like Java reference variables, but I haven't used Java at all and I
> could easily have that confused (or have been told inaccurately).

Java has object reference variables instead of pointers, but there
is no dereference operator. If you assign one, it copies the reference.
Arrays (which are Objects) you dereference with []. Multidimensional
arrays are arrays of arrays, and dereferenced with multiple [].
Otherwise, an Object has more similarity to a structure, and is
dereferenced by the . operation. Any other operation, such as the
previously mentioned deep copy, is done by a method invocation.

All variables are passed by value, either the value of a primitive
(char, short, int, long, etc.) or the value of an Object reference.
If you don't change the value of the (I forget what Java calls
dummy variables) then it looks like call by reference, but you can
change the local Object reference.

The == operator will compare the Object reference, not the Object.
The equalTo() and compareTo() methods allow comparison of objects.

-- glen

Ian Harvey

unread,
May 7, 2013, 8:20:17 PM5/7/13
to
An aside - as it was recently pointed out to me on this group, there's
potential for a break in compatibility with the above from F2003 to
F2008 thats the subject of a current interp (F08/0089). In F2003, the
actual argument above is an expression. In F2008 it is a variable.
Depending on what happens inside do_something that can have implications
in the context of the dummy argument aliasing restrictions.

It is akin to going from and actual argument list of:
call do_something(..., (variable), ...)

to:
call do_something(..., variable, ...)


>
> (using a pointer if 'f' is large so you don't get a temporary copy).

Mind you, when you read some discussion the interp you can see that
under F2003 rules you probably should still be getting a temporary copy,
in the absence of the implementation working out that there's no
possibility for aliasing inside the do_something procedure.


Wolfgang Kilian

unread,
May 8, 2013, 3:35:24 AM5/8/13
to
On 05/08/2013 02:20 AM, Ian Harvey wrote:
> On 2013-05-07 6:42 PM, Wolfgang Kilian wrote:
>> On 05/07/2013 08:00 AM, glen herrmannsfeldt wrote:
>>> Richard Maine <nos...@see.signature> wrote:
>>>
>>> (snip)

>> Furthermore, one can't use a subroutine argument as the argument to
>> another procedure without introducing a variable in the caller's scope.
>> While avoiding the pitfalls of pointer functions, one introduces some
>> overhead on the caller's side. Consider
>>
>> call do_something (..., abc%f, ...)
>>
>> which you may later want to change into
>>
>> call do_something (..., abc%get_f_ptr (), ...)
>
> An aside - as it was recently pointed out to me on this group, there's
> potential for a break in compatibility with the above from F2003 to
> F2008 thats the subject of a current interp (F08/0089). In F2003, the
> actual argument above is an expression. In F2008 it is a variable.
> Depending on what happens inside do_something that can have implications
> in the context of the dummy argument aliasing restrictions.
>
> It is akin to going from and actual argument list of:
> call do_something(..., (variable), ...)
>
> to:
> call do_something(..., variable, ...)
>
>> (using a pointer if 'f' is large so you don't get a temporary copy).
>
> Mind you, when you read some discussion the interp you can see that
> under F2003 rules you probably should still be getting a temporary copy,
> in the absence of the implementation working out that there's no
> possibility for aliasing inside the do_something procedure.

So, can one avoid the expression interpretation (F2003) and thus
temporaries, for both calls? My guess is that

do_something (...., f, ...)
type(...), intent(in), pointer :: f

would do this, but works only with the second form of the call. What about

do_something (...., f, ...)
type(...), intent(in), target :: f

?

-- Wolfgang

Ian Harvey

unread,
May 8, 2013, 6:03:14 AM5/8/13
to
I got very, very confused about this a week or two ago [and that
confusion continues], so take everything here with a grain of salt.

Under F2003, formally? I don't think so. Practically though, yes.

This is just a mish-mash of existing interps (F95/0074 and F08/0089),
nothing new, but to mess with your head:

PROGRAM
INTEGER, TARGET :: x
x = 1
CALL sub(x, fun())
CONTAINS
SUBROUTINE sub(a, b)
INTEGER, INTENT(INOUT), TARGET :: a
INTEGER, TARGET :: b
INTEGER, POINTER :: c
!***
a = a + 1
PRINT "('first numbers ',3(I0,:,','))", a, b, x
c => b
c = c + 1
PRINT "('second numbers ',I0)", a, b, x
END SUBROUTINE sub
FUNCTION fun()
INTEGER, POINTER :: fun
fun => x
END FUNCTION fun
END PROGRAM

I *think* this is both legal F2003 and F2008. All arguments are targets
or pointers so the aliasing restrictions fly away.

Under F2008 you get first numbers 2, 2, 2 and second numbers 3, 3, 3.
a, b, c, x are the same thing,

Under F2003 I get very scared. b is associated with an expression, so b
and a aren't the same thing in sub (yes? no? maybe?). So that means
that you get first numbers 2, 1, 2. But then F95/0074 answer three
says(*) c => b means c gets associated with x. x is definable, so we
can define the target of c? But c => b presumably means c is also
associated with b, or we've been typing a lot of pointer assignment
statements for no good reason. (b is associated with an expression. On
its own that's not definable. Perhaps that's where this all goes
wrong.) We already know a is associated with x. So a, b, c, and x are
all the same. Sort of. Perhaps. So we get second numbers of 3, 1, 3
and 3, 3, 3 at the same time.

[*] I'm not totally sure how F95/0074 answer 3 comes to the conclusion
that it does, perhaps I'm abusing its conclusions. Under F2003, I
*think* the only sane logic is that the result of evaluating any
expression gives a value, and values are not targets when used as actual
arguments, so pointers pointing at the associated dummy argument can not
then be considered to be pointing at a potentially definable object.

Wolfgang Kilian

unread,
May 8, 2013, 10:11:00 AM5/8/13
to
This is indeed scaring, but I think the answer is unambiguous.

The result of evaluating a pointer-function reference is a pointer
(12.2.2), possibly associated with a target.

Sec. 7.1.4.1 of F2003 mentions pointers as possible results of
evaluating an expression. It also lists cases where the associated
target is referenced instead. This list does not include the
actual-argument case. Probably the list is not exhaustive?

Sec. 12.4.1.2 covers argument association. Here, the actual is a
pointer. If the dummy has the TARGET attribute, I see only two
possibilities: (1) The actual is not dereferenced. Then association is
not possible at all. (2) The actual is dereferenced, although this is
not listed in 7.1.4.1. The target has the TARGET attribute, so the
actual has the TARGET attribute. Then pointers associated with the
actual become pointers associated with the dummy and vice versa. My
understanding of F95/0074 is that option (2) is declared as valid.

So, in your example, b is not associated with the expression, but with
the target of the pointer which is the expression result, x. The dummy
a is also associated with this target. c is a pointer to this target.
Since both dummies have the TARGET attribute and are not INTENT(IN),
modification via a or c is allowed and does affect the value of b.

The numbers should be 2,2,2 and 3,3,3 as with F2008. I do get those
with gfortran and nagfor.

I don't find F08/0089, is that online somewhere?

Tobias Burnus

unread,
May 8, 2013, 2:03:00 PM5/8/13
to
Wolfgang Kilian wrote:
>> This is just a mish-mash of existing interps (F95/0074 and F08/0089),
> I don't find F08/0089, is that online somewhere?

Search for it in http://www.j3-fortran.org/doc/year/13/13-255r1.txt

Tobias

Ian Harvey

unread,
May 8, 2013, 6:10:43 PM5/8/13
to
I think that action is listed in the section on arguments in 12.4.1.2p8,
assuming here that the result of evaluating a function with data pointer
result in the context of an expression (versus the right hand side of a
pointer assignment statement) is still considered a pointer. Do you
still have a pointer after the expression is evaluated, noting that
evaluation of actual argument expressions clearly happens before
argument association and "evaluation of an expression produces a value".
Can a value be a pointer?

The definability of a dummy is subject to the definability of the
effective argument (or words like that) - I don't think there is
anything more specific than that. In the answer to F95/0089 Q1, the
effective argument is said to be the result of evaluation of an
expression, and that is then said to not be definable because (wave
hands) it "is an expression". But then 0074 turns around two minutes
later and implicitly says what you posit above - that the thing that is
associated with the dummy argument is really the target of the pointer -
i.e. the thing that is the effective argument *is* the variable `x` in
the host scope above. But that thing that is the effective argument is
definable. So ... what stops the dummy from being definable in the Q1 case?

> The target has the TARGET attribute, so the
> actual has the TARGET attribute.

This appears to be the inference of F95/0074, but I'm not sure of the
justification. In addition to the above blather from me - things can be
associated with targets, and the associated entity does not magically
get the target attribute.

Then pointers associated with the
> actual become pointers associated with the dummy and vice versa. My
> understanding of F95/0074 is that option (2) is declared as valid.

I agree with your understanding that 'that is what that interp says',
but I'm not robust in my understanding as to how that interp got there.

> So, in your example, b is not associated with the expression, but with
> the target of the pointer which is the expression result, x. The dummy
> a is also associated with this target. c is a pointer to this target.
> Since both dummies have the TARGET attribute and are not INTENT(IN),
> modification via a or c is allowed and does affect the value of b.
>
> The numbers should be 2,2,2 and 3,3,3 as with F2008. I do get those
> with gfortran and nagfor.
>
> I don't find F08/0089, is that online somewhere?

Rafik Zurob posted a link a week or two ago here. I've been using:

F95/0074: http://j3-fortran.org/doc/standing/links/016.txt
F08/0089: http://j3-fortran.org/doc/year/13/13-228r2.txt

F08/0089 is still under consideration, but note the semantics that
question 2 assumes applied under F2003.

I recall reading somewhere while I was trying to confuse myself further
about this an observation that most compilers got the F2003 semantics
"wrong" (though that was possibly as part of a debate about what those
semantics were).

Mind you, regardless of the answer, this all goes towards Richard's
assertions that functions with pointer results are evil, because
understanding their semantics runs the risk of confusion.

By making it explicit in the syntax rules that functions with pointer
results are variables, F2008 simplifies this, with the downside of a
break in compatibility for some corner cases.

Richard Maine

unread,
May 8, 2013, 6:56:28 PM5/8/13
to
Ian Harvey <ian_h...@bigpond.com> wrote:

> Mind you, regardless of the answer, this all goes towards Richard's
> assertions that functions with pointer results are evil, because
> understanding their semantics runs the risk of confusion.
>
> By making it explicit in the syntax rules that functions with pointer
> results are variables, F2008 simplifies this, with the downside of a
> break in compatibility for some corner cases.

Let me add that I'll not jump into the discussion of the interp in
question. (Does that make this a silly post just to say that I'm not
saying anything? Probably. Oh well.)

I recall that interp comming up for f2003. I certainly forget all the
fine points of the debate, though I somewhat recall not being
particularly pleased with it. I do remember that the concluion was
basically that "this is what f2003 says, even if we don't particularly
like that, but we could change it in f2008". I'm not sure I was
convinced that f2003 unambiguously said what was claimed, but that's
what passed as the interp anyway.

Yeah, I just said something after all, but a bit low on content.

robert....@oracle.com

unread,
May 8, 2013, 7:09:29 PM5/8/13
to
On Wednesday, May 8, 2013 7:11:00 AM UTC-7, Wolfgang Kilian wrote:
>
> I don't find F08/0089, is that online somewhere?

The URL for the current list of active interpretations is

http://www.j3-fortran.org/doc/year/13/13-006A.txt

Interpretation F08/0089 is still being balloted. It was passed at the last meeting, and it was balloted at the INCITS PL22.3 level. It has yet to be balloted at the WG5 level.

Robert Corbett

glen herrmannsfeldt

unread,
May 8, 2013, 8:45:18 PM5/8/13
to
Ian Harvey <ian_h...@bigpond.com> wrote:
> On 2013-05-09 12:11 AM, Wolfgang Kilian wrote:

(snip, someone wrote)
>>>>>> call do_something (..., abc%get_f_ptr (), ...)

As is sometimes discussed here, Fortran does not require call by
reference. An alternative is call by value result (copy-in/copy-out).

(snip)

>>> PROGRAM
>>> INTEGER, TARGET :: x
>>> x = 1
>>> CALL sub(x, fun())

In the call by reference case, the obvious choice is to pass the
pointer (reference) to the callee. In the call by value result case,
the callee gets a copy of the original value.

>>> CONTAINS
>>> SUBROUTINE sub(a, b)
>>> INTEGER, INTENT(INOUT), TARGET :: a
>>> INTEGER, TARGET :: b

Unless the standard says differently, this seems to me to
allow pointers to the dummy argument.

If you also give it the POINTER attribute, then the pointer
value should be passed through (either by reference or value result).

>>> INTEGER, POINTER :: c
>>> !***
>>> a = a + 1
>>> PRINT "('first numbers ',3(I0,:,','))", a, b, x
>>> c => b
>>> c = c + 1
>>> PRINT "('second numbers ',I0)", a, b, x
>>> END SUBROUTINE sub
>>> FUNCTION fun()
>>> INTEGER, POINTER :: fun
>>> fun => x
>>> END FUNCTION fun
>>> END PROGRAM

>>> I *think* this is both legal F2003 and F2008. All arguments
>>> are targets or pointers so the aliasing restrictions fly away.

Do they really fly away, or just have to be looked at more carefully?

>>> Under F2008 you get first numbers 2, 2, 2 and second numbers
>>> 3, 3, 3. a, b, c, x are the same thing,

(snip)

>> This is indeed scaring, but I think the answer is unambiguous.

>> The result of evaluating a pointer-function reference is a pointer
>> (12.2.2), possibly associated with a target.

-- glen

robert....@oracle.com

unread,
May 8, 2013, 10:06:59 PM5/8/13
to
The program does not conform to the Fortran 2003 standard. In Fortran 2003, the actual argument fun() is an expression, not a variable. Therefore, dummy argument b of sub is not definable. In earlier editions of the standard, that was clearly stated. The answer to question 1 of interpretation makes it clear that it was true for Fortran 95. Because the relevant text did not change in Fortran 2003, it should still be true for Fortran 2003. Paragraph 4 of Clause 7.4.1.2 of the Fortran 2003 standard [139:11-12] states

If <variable> is a pointer, it shall be
associated with a definable target such
that the type, type parameters, and shape
of the target and <expr> conform.

During the assignment to c, the pointer c is associated with b, which is not definable.

As for your issue regarding the answer given to question 3 of interpretation F95/0074, I agree that the rationale given for the answer is dodgy, but the answer itself is clear. It imposes an otherwise unstated restriction on the way processors implement argument passing. A compiler writer might ask what would happen if the actual argument that is a pointer-valued function reference were enclosed in parentheses.

Ian Harvey

unread,
May 8, 2013, 11:47:09 PM5/8/13
to
Ok, how about this one...

PROGRAM i_should_stop_procrastinating
INTEGER, POINTER :: x
IMPLICIT NONE
ALLOCATE(x)
x = 1
CALL sub(x, fun())
CONTAINS
SUBROUTINE sub(a, b)
INTEGER, TARGET :: a, b
a = 2
PRINT *, ASSOCIATED(x, b), a, b, x
END SUBROUTINE sub
FUNCTION fun()
INTEGER, POINTER :: fun
fun => x
END FUNCTION fun
END PROGRAM i_should_stop_procrastinating

- My understanding is that a is argument associated with the target of x.
- F95/0074 answer three implies to me that x and b are associated.
- F08/0089 *question* two implies that under F2003 a will have the value
2 at the print statement and b will have the value 1.

So we're all associated in some form, but we have different values?

Is question two of 0089 based off a false premise?

Ian Harvey

unread,
May 8, 2013, 11:54:04 PM5/8/13
to
On 2013-05-09 1:47 PM, Ian Harvey wrote:
...
> Ok, how about this one...
>
> PROGRAM i_should_stop_procrastinating
> INTEGER, POINTER :: x
> IMPLICIT NONE

(well, basic statement ordering errors aside.)


robert....@oracle.com

unread,
May 9, 2013, 12:17:39 AM5/9/13
to
That one looks bad. I am inclined to think the problem is with the answer to F95/0074 than with the answer to F08/0089.

Bob Corbett

robert....@oracle.com

unread,
May 9, 2013, 9:51:33 PM5/9/13
to
On Wednesday, May 8, 2013 7:06:59 PM UTC-7, robert....@oracle.com wrote:

> The program does not conform to the Fortran 2003 standard. In Fortran 2003, the actual argument fun() is an expression, not a variable. Therefore, dummy argument b of sub is not definable. In earlier editions of the standard, that was clearly stated. The answer to question 1 of interpretation makes it clear that it was true for Fortran 95. Because the relevant text did not change in Fortran 2003, it should still be true for Fortran 2003. Paragraph 4 of Clause 7.4.1.2 of the Fortran 2003 standard [139:11-12] states
>
> If <variable> is a pointer, it shall be
> associated with a definable target such
> that the type, type parameters, and shape
> of the target and <expr> conform.
>
> During the assignment to c, the pointer c is associated with b, which is not definable.
>
> As for your issue regarding the answer given to question 3 of interpretation F95/0074, I agree that the rationale given for the answer is dodgy, but the answer itself is clear. It imposes an otherwise unstated restriction on the way processors implement argument passing. A compiler writer might ask what would happen if the actual argument that is a pointer-valued function reference were enclosed in parentheses.

I changed my mind. My response was based on the answer given to question 1 in interpretation F95/0074. The answer claims that the Fortran 2003 standard causes the dummy argument to be argument associated with the corresponding actual argument. The Fortran 2003 explicitly states otherwise. Paragraph 8 of Clause 12.4.1.2 states

Except in references to intrinsic inquiry
functions, if the dummy argument is not a
pointer and the corresponding actual
argument is a pointer, the actual argument
shall be associated with a target and the
dummy argument becomes argument associated
with that target.

In the example given, the target of the pointer returned by the function reference fun() is the variable x. The dummy argument becomes argument associated with the variable x, and because the variable x is definable, the dummy argument is definable.

Robert Corbett

glen herrmannsfeldt

unread,
May 10, 2013, 1:18:39 AM5/10/13
to
robert....@oracle.com wrote:
> On Wednesday, May 8, 2013 7:06:59 PM UTC-7, robert....@oracle.com wrote:

>> The program does not conform to the Fortran 2003 standard.
>> In Fortran 2003, the actual argument fun() is an expression,
>> not a variable. Therefore, dummy argument b of sub is not definable.

(snip)

> I changed my mind. My response was based on the answer given to
> question 1 in interpretation F95/0074. The answer claims that the
> Fortran 2003 standard causes the dummy argument to be argument
> associated with the corresponding actual argument.
> The Fortran 2003 explicitly states otherwise.
> Paragraph 8 of Clause 12.4.1.2 states

> Except in references to intrinsic inquiry
> functions, if the dummy argument is not a
> pointer and the corresponding actual
> argument is a pointer, the actual argument
> shall be associated with a target and the
> dummy argument becomes argument associated
> with that target.

But does this disallow copy-in/copy-out?

Or, as noted previously, does TARGET do what the OP says,
and throw the aliasing rules out? Seems to me that aliasing
still needs to be considered, though maybe not the same as without
pointers.

> In the example given, the target of the pointer returned by the
> function reference fun() is the variable x. The dummy argument
> becomes argument associated with the variable x, and because the
> variable x is definable, the dummy argument is definable.

For usual argument association, copy-in/copy-out is allowed.

-- glen

robert....@oracle.com

unread,
May 10, 2013, 2:14:01 AM5/10/13
to
On Thursday, May 9, 2013 10:18:39 PM UTC-7, glen herrmannsfeldt wrote:
> robert....@oracle.com wrote:
>
> > Fortran 2003 explicitly states otherwise.
>
> > Paragraph 8 of Clause 12.4.1.2 states
>
> > Except in references to intrinsic inquiry
> > functions, if the dummy argument is not a
> > pointer and the corresponding actual
> > argument is a pointer, the actual argument
> > shall be associated with a target and the
> > dummy argument becomes argument associated
> > with that target.
>
> But does this disallow copy-in/copy-out?

No. The argument association between the dummy argument and the target is subject to the same rules as any other argument association.

> Or, as noted previously, does TARGET do what the OP says,
> and throw the aliasing rules out? Seems to me that aliasing
> still needs to be considered, though maybe not the same as without
> pointers.

Giving a dummy argument the TARGET attribute limits what a processor can do. The exact rules are somewhat involved. The version of the rules in the Fortran 2008 standard are the clearest thus far.

Bob Corbett

Ian Harvey

unread,
May 10, 2013, 5:11:04 AM5/10/13
to
To clarify - was the bit you changed your mind about whether the program
conforms or not, or some other aspect?


Wolfgang Kilian

unread,
May 10, 2013, 5:21:15 AM5/10/13
to
On 05/09/2013 12:10 AM, Ian Harvey wrote:
> On 2013-05-09 12:11 AM, Wolfgang Kilian wrote:
>> On 05/08/2013 12:03 PM, Ian Harvey wrote:
[...]
To me (as an outsider) it looks like in the interp F95/0074, one missed
an opportunity to clarify this by an addendum to F2003, Sec. 7.1, which
could cover the semantics of expressions in all contexts but apparently
doesn't. (The relevant parts reappear also in F2008, essentially
unchanged.)
[...]

> By making it explicit in the syntax rules that functions with pointer
> results are variables, F2008 simplifies this, with the downside of a
> break in compatibility for some corner cases.

But I understand that the compatibility break occurs only for
unspecified intent of dummy arguments, correct? Another reason to
always specify intent (in new code, at least).

Wolfgang Kilian

unread,
May 10, 2013, 8:36:28 AM5/10/13
to
On 05/09/2013 12:10 AM, Ian Harvey wrote:

> Rafik Zurob posted a link a week or two ago here. I've been using:
>
> F95/0074: http://j3-fortran.org/doc/standing/links/016.txt
> F08/0089: http://j3-fortran.org/doc/year/13/13-228r2.txt
>
> F08/0089 is still under consideration, but note the semantics that
> question 2 assumes applied under F2003.
>
> I recall reading somewhere while I was trying to confuse myself further
> about this an observation that most compilers got the F2003 semantics
> "wrong" (though that was possibly as part of a debate about what those
> semantics were).

Thanks (to you and others) for the link. Isn't the F2003 semantics
assumed in F08/0089,Q2 a plain contradiction to the semantics declared
by F95/0074?

> Mind you, regardless of the answer, this all goes towards Richard's
> assertions that functions with pointer results are evil, because
> understanding their semantics runs the risk of confusion.

I still see the most (only?) useful application of pointer functions in
precisely this context, and I have written code like this (but with
argument intent!) many times -- when subobjects are private, it's good
to have getter methods at hand that don't physically copy data. At
least, F2008 should establish this behavior.

-- Wolfgang

(@Ian: sorry for accidental PM, if it reached you.)

robert....@oracle.com

unread,
May 10, 2013, 6:31:49 PM5/10/13
to
I changed my mind regarding which answer given in interpretation F95/0074 is a mistake. The reason given for the answer to question 3 is weak, but the reason given for the answer to question 1 is based on a false premise. I think the answer to question 1 should have been that the program is conforming.

Although I believe the answer to question 1 to be mistaken, that does not mean the committees involved will agree. For now, the interpretation stands and the program is not conforming.

Bob Corbett

robert....@oracle.com

unread,
May 10, 2013, 7:55:02 PM5/10/13
to
On Wednesday, May 8, 2013 7:11:00 AM UTC-7, Wolfgang Kilian wrote:
>
> This is indeed scaring, but I think the answer is unambiguous.
>
> The result of evaluating a pointer-function reference is a pointer
> (12.2.2), possibly associated with a target.
>
> Sec. 7.1.4.1 of F2003 mentions pointers as possible results of
> evaluating an expression. It also lists cases where the associated
> target is referenced instead. This list does not include the
> actual-argument case. Probably the list is not exhaustive?

The list is exhaustive for the portion of the semantics covered by that clause. The semantics used to cover the case of actual arguments, but that bit was removed by interpretation F90/000039, which has the names Maine and Martin attached to it. F90/000039 can be found in

http://www.j3-fortran.org/doc/year/94/94-006r3/94-006r3.A0

Bob Corbett

Richard Maine

unread,
May 10, 2013, 8:25:32 PM5/10/13
to
<robert....@oracle.com> wrote:

> interpretation F90/000039, which has the names Maine and Martin attached
> to it. F90/000039 can be found in
> http://www.j3-fortran.org/doc/year/94/94-006r3/94-006r3.A0

This isn't a particular detail that I recall from 20 years ago (1993
according to the citation), but please do note that the only sense in
which the names Maine and Martin are obviously "attached" in the
document cited is that we were mentioned as having offerred edits that
were accepted. I really don't recall anything about it, but that doesn't
say much about whether Jean (Martin) or myself did or did not have much
to do with the interp. Indeed, if the edits were accepted on the floor
without producing a new document, odds are that they were prettty
trivial edits on the order of grammatical corrections. It probably also
means that we did not write the interp response, as it would be slightly
odd for us to be proposing edits to our own paper (not unheard of, but
not the norm either).

Wolfgang Kilian

unread,
May 13, 2013, 2:44:08 AM5/13/13
to
The intp F90/000039 which you quoted elsethread, should already have
clarified the issue. Taking the answer and discussion there at face
value, one could even conclude that the 'new' F08 semantics (a pointer
expression as actual argument is replaced by its target, which can be
definable) is conforming already to the F90 standard.

It is a bit unfortunate that, in F90/000039, the notion of dereferencing
a pointer was considered an implementation detail. The issues of
pointer association (with the target and/or dummy) and (maybe)
definability depend on it, so it does affect the semantics.

Personally, I would greatly appreciate it if the compiler writers
implement (or just keep, where applicable) the F08 semantics in that
context. It is very useful in practice.

robert....@oracle.com

unread,
May 13, 2013, 11:20:56 PM5/13/13
to
On Sunday, May 12, 2013 11:44:08 PM UTC-7, Wolfgang Kilian wrote:
> On 05/11/2013 12:31 AM, robert....@oracle.com wrote:

> > I changed my mind regarding which answer given in interpretation F95/0074 is a mistake. The reason given for the answer to question 3 is weak, but the reason given for the answer to question 1 is based on a false premise. I think the answer to question 1 should have been that the program is conforming.
> >
> > Although I believe the answer to question 1 to be mistaken, that does not mean the committees involved will agree. For now, the interpretation stands and the program is not conforming.
> >
> > Bob Corbett
> >
> The intp F90/000039 which you quoted elsethread, should already have
> clarified the issue. Taking the answer and discussion there at face
> value, one could even conclude that the 'new' F08 semantics (a pointer
> expression as actual argument is replaced by its target, which can be
> definable) is conforming already to the F90 standard.

I agree that the answers given in F95/0074 are inconsistent with interpretation F90/000039. They are also inconsistent with the text added to the Fortran 90 standard by the edits in F90/000039; text that is still included in the Fortran 2008 standard. However, F95/0074 is a later interpretation than F90/000039, and so it takes precedence.

I was happy to find that interpertation F95/0074 was approved before I joined the committee.

Bob Corbett

David Thompson

unread,
May 16, 2013, 3:12:23 AM5/16/13
to
Straying from topic but I think the comparisons are interesting.

On Wed, 8 May 2013 00:13:38 +0000 (UTC), glen herrmannsfeldt
<g...@ugcs.caltech.edu> wrote:

> Richard Maine <nos...@see.signature> wrote:
> > Nicolas Bock <nicol...@gmail.com> wrote:
> > <snip> In most contexts, a pointer acts just
> > as though you had used the target directly. Another way of describing
> > this is that pointers are automatically dereferenced. You don't do
> > anything like the c "^" to dereference the pointer; just using the
> > pointer name as is already implies dereferencing.
>
> You mean *. (I haven't done Pascal for a while, it might be ^ there.)
>
Yes; C is prefix * and Pascal is postfix ^ . C subscripting a[i] is
actually defined in terms of pointer arithmetic as *(a+i), so postfix
[0] functions as an extra-clumsy dereference operator.

<snip>
> > I am told (if I recall correctly) that Fortran pointers are somewhat
> > like Java reference variables, but I haven't used Java at all and I
> > could easily have that confused (or have been told inaccurately).
>
> Java has object reference variables instead of pointers, but there
> is no dereference operator. If you assign one, it copies the reference.
> Arrays (which are Objects) you dereference with []. Multidimensional
> arrays are arrays of arrays, and dereferenced with multiple [].

Yes. You can also read .length of an array, but it's not clear to me
if that's actually with the array body/elements or not.

> Otherwise, an Object has more similarity to a structure, and is
> dereferenced by the . operation. Any other operation, such as the
> previously mentioned deep copy, is done by a method invocation.
>
Mostly. A class reference is actually dereferenced only by fetching or
storing a field. Often this is done by obj.fieldname, but for 'this'
references within a non-static method or ctor or init-block you can
use just fieldname. Conversely obj.method(...) calls pass the objref
to the method if non-static, but don't dereference it. And you can
access both static fields and static methods using obj.name, but the
actual object is ignored and only the declared reference type is used.
(Eclipse normallly warns for this like 'should use static access'.)

> All variables are passed by value, either the value of a primitive
> (char, short, int, long, etc.) or the value of an Object reference.
> If you don't change the value of the (I forget what Java calls
> dummy variables) then it looks like call by reference, but you can
> change the local Object reference.
>
Java like C (and C++) and PL/I uses actual 'argument' and formal
'parameter'. Pascal and Ada use actual and formal 'parameter'. COBOL I
don't have the standard and IME implementations aren't consistent,
although the syntax overhead plus convenience of PERFORM as a cheap
quasi-call with no explicit data encouraged large procedures and few
real calls. Fortran (of course) uses actual and dummy 'argument'.

> The == operator will compare the Object reference, not the Object.

Yes. Or more exactly not the objects, which can be any nonprimitive
type not necessarily java.lang.Object. A reference to any object can
be converted to reference to Object, but the object itself retains its
specific type like String or HashSet<T> or FileInputStream etc., and
the reference to Object can be cast back to reference to the actual
type or any other superclass or interface of it, but not an unrelated
reference type. And != equivalently of course.

> The equalTo() and compareTo() methods allow comparison of objects.
>
Somewhat.

.equals(Object) (not equalTo) is declared in Object and so exists for
all objects; but the default implementation in Object just compares
the references, like ==. Classes where a different equality relation
makes sense must override; for example java.lang.String implements
.equals to check if the two String's contain the same sequence of
characters. Arrays inherit only from Object and use the default
reference-equals, but java.util.Arrays provides (overloaded) static
.equals(a,b) methods that compare the contents.

<T>.compareTo(T) is declared by interface java.lang.Comparable, which
is used for some standard classes but not all. It is not implemented
for arrays directly nor in java.util.Arrays, nor anywhere else in the
standard JRE that I have found. User classes can of course implement
it if and as chosen.

glen herrmannsfeldt

unread,
May 16, 2013, 12:35:15 PM5/16/13
to
David Thompson <dave.th...@verizon.net> wrote:

(snip, I wrote)
>> You mean *. (I haven't done Pascal for a while,
>> it might be ^ there.)

> Yes; C is prefix * and Pascal is postfix ^ . C subscripting a[i] is
> actually defined in terms of pointer arithmetic as *(a+i), so postfix
> [0] functions as an extra-clumsy dereference operator.

> <snip>
>> > I am told (if I recall correctly) that Fortran pointers are somewhat
>> > like Java reference variables, but I haven't used Java at all and I
>> > could easily have that confused (or have been told inaccurately).

>> Java has object reference variables instead of pointers, but there
>> is no dereference operator.

(snip)
> Yes. You can also read .length of an array, but it's not clear to me
> if that's actually with the array body/elements or not.

Seems to me that, as with much of Java, it is an implementation
detail. Maybe with timing cache access patterns you could tell,
but otherwise not.

>> Otherwise, an Object has more similarity to a structure, and is
>> dereferenced by the . operation. Any other operation, such as the
>> previously mentioned deep copy, is done by a method invocation.

> Mostly. A class reference is actually dereferenced only by fetching or
> storing a field. Often this is done by obj.fieldname, but for 'this'
> references within a non-static method or ctor or init-block you can
> use just fieldname.

So, not as general as the partial qualification for structure
references in PL/I. In PL/I, you can leave out intermediate
(or the base) qualifiers for structure references as long as it
isn't ambiguous. PL/I also has structure expressions.

> Conversely obj.method(...) calls pass the objref
> to the method if non-static, but don't dereference it. And you can
> access both static fields and static methods using obj.name, but the
> actual object is ignored and only the declared reference type is used.
> (Eclipse normallly warns for this like 'should use static access'.)

>> All variables are passed by value, either the value of a primitive
>> (char, short, int, long, etc.) or the value of an Object reference.
>> If you don't change the value of the (I forget what Java calls
>> dummy variables) then it looks like call by reference, but you can
>> change the local Object reference.

> Java like C (and C++) and PL/I uses actual 'argument' and formal
> 'parameter'. Pascal and Ada use actual and formal 'parameter'. COBOL I
> don't have the standard and IME implementations aren't consistent,
> although the syntax overhead plus convenience of PERFORM as a cheap
> quasi-call with no explicit data encouraged large procedures and few
> real calls. Fortran (of course) uses actual and dummy 'argument'.

>> The == operator will compare the Object reference, not the Object.

> Yes. Or more exactly not the objects, which can be any nonprimitive
> type not necessarily java.lang.Object. A reference to any object can
> be converted to reference to Object,

Yes. Object or subclass of Object.

I think we still didn't answer the question about what Fortran
does for non-pointer assignment of structure containing
allocatables or pointers, though.

-- glen

Richard Maine

unread,
May 16, 2013, 1:22:37 PM5/16/13
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> I think we still didn't answer the question about what Fortran
> does for non-pointer assignment of structure containing
> allocatables or pointers, though.

Did someone ask that question? I suppose I might have missed it. Much of
this thread is old enough that I can't easily see it any more. In any
case, the answer is completely different for allocatables and pointers.

For pointers, you get pointer assignment of the components.

For allocatables, you get...well... the only kind of assignment that
there ever is for allocatables in any context; it isn't as though there
are any alternatives to choose from for allocatables, making the
question somewhat moot.

glen herrmannsfeldt

unread,
May 16, 2013, 2:40:31 PM5/16/13
to
Richard Maine <nos...@see.signature> wrote:
> glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

>> I think we still didn't answer the question about what Fortran
>> does for non-pointer assignment of structure containing
>> allocatables or pointers, though.

> Did someone ask that question? I suppose I might have missed it. Much of
> this thread is old enough that I can't easily see it any more. In any
> case, the answer is completely different for allocatables and pointers.

Well, the question was shallow or deep copy.

> For pointers, you get pointer assignment of the components.

That seemed most likely to avoid the loops that would otherwise
happen, for example with circularly linked lists. So not shallow
or deep, but in between.

> For allocatables, you get...well... the only kind of assignment that
> there ever is for allocatables in any context; it isn't as though there
> are any alternatives to choose from for allocatables, making the
> question somewhat moot.

And recursively, however deep it goes? That is, structures
containing allocatables containing structures containing
allocatables on down? Even more interesting if one contains
an allocatable member of its own type.

Fortunately you can't have loops.

-- glen

Richard Maine

unread,
May 16, 2013, 4:15:25 PM5/16/13
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Richard Maine <nos...@see.signature> wrote:
> > glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
>
> >> I think we still didn't answer the question about what Fortran
> >> does for non-pointer assignment of structure containing
> >> allocatables or pointers, though.

> > For allocatables, you get...well... the only kind of assignment that
> > there ever is for allocatables in any context; it isn't as though there
> > are any alternatives to choose from for allocatables, making the
> > question somewhat moot.
>
> And recursively, however deep it goes? That is, structures
> containing allocatables containing structures containing
> allocatables on down?

Yes. As I said, it is the only kind of assignment that there ever is for
allocatables. Yes, you can have structures containing allocatables
containing structures containing allocatables, etc. And yes, you can do
assignment of such structures. Thus, yes, that is a context that can
happen. See above about there being only one kind of assignment for
allocatables. Q.E.D. Turtles all the way down.

> Even more interesting if one contains
> an allocatable member of its own type.
>
> Fortunately you can't have loops.

I'm not sure what makes this "interesting". I see no special
complications. As you say, you can't have loops, so it is a finite
process, with each step being well defined.

I think you have to go to f2008 for a structure to have an allocatable
component of its own type (though I don't feel like dragging out the
docs to check). As I recall, there was an interp question about why it
wasn't allowed in f2003. My recollection of the answer is that there was
no good reason not to allow it and that it was basically just an
oversight not to do so. But it was considered improper to add a feature
like that via the interpretation process. I recall no objections at all
based on technical problems - just the procedural objection about doing
it via an interp, and some debate about whether the omission of that
feature might have actually constituted an error. I'm pretty sure that
the final answer was that it ought to be allowed, but we had to wait til
the next standard to do so.

glen herrmannsfeldt

unread,
May 16, 2013, 6:23:22 PM5/16/13
to
Richard Maine <nos...@see.signature> wrote:

(snip)
>> > For allocatables, you get...well... the only kind of assignment that
>> > there ever is for allocatables in any context; it isn't as though there
>> > are any alternatives to choose from for allocatables, making the
>> > question somewhat moot.

(snip, then I wrote)
>> And recursively, however deep it goes? That is, structures
>> containing allocatables containing structures containing
>> allocatables on down?

> Yes. As I said, it is the only kind of assignment that there ever is for
> allocatables. Yes, you can have structures containing allocatables
> containing structures containing allocatables, etc. And yes, you can do
> assignment of such structures. Thus, yes, that is a context that can
> happen. See above about there being only one kind of assignment for
> allocatables. Q.E.D. Turtles all the way down.

OK, so in the usual CS terminology, deep copy.

>> Even more interesting if one contains
>> an allocatable member of its own type.

>> Fortunately you can't have loops.

> I'm not sure what makes this "interesting". I see no special
> complications. As you say, you can't have loops, so it is a finite
> process, with each step being well defined.

> I think you have to go to f2008 for a structure to have an allocatable
> component of its own type (though I don't feel like dragging out the
> docs to check).

Looks that way to me. After the post, I tried it in the version of
gfortran on this computer (which doesn't belong to me) and it
didn't allow it. The I looked in N1830 and it seemed to be there.

Funny, when I was testing it out, at one point I had a structure
with a line:

type(deep) :: pointer

and got the error message something like "must have pointer attribute"

and I looked at it a few seconds wondering what it was complaining
about, as it was pointing right at the word "pointer".
(Only a few seconds before I figured it out.)

> As I recall, there was an interp question about why it
> wasn't allowed in f2003. My recollection of the answer is that
> there was no good reason not to allow it and that it was basically
> just an oversight not to do so.

Without actually looking up what PL/I did, and when, my feeling
overall is that the PL/I committee would have done it the other
way around. That is, asked if there was a reason NOT to do it.

Well, pointers were part of list processing (specifically
described that way) and would have had to allow it for
linked lists. It is slightly less obvious for allocatables.

-- glen

Richard Maine

unread,
May 16, 2013, 6:58:49 PM5/16/13
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Funny, when I was testing it out, at one point I had a structure
> with a line:
>
> type(deep) :: pointer
>
> and got the error message something like "must have pointer attribute"
>
> and I looked at it a few seconds wondering what it was complaining
> about, as it was pointing right at the word "pointer".
> (Only a few seconds before I figured it out.)

Been there. Done things much like that.

A somewhat simillar one that I've seen, though not done myself, is a
declaration like

double precision integer i

where the writer was trying to get a large integer and guessed the
syntax for such a thing. With fixed source form (for the blank
insignificance) and implicit typing not disabled, that one tends to
compile just fine, although not with the expected results.

Dick Hendrickson

unread,
May 17, 2013, 11:11:28 AM5/17/13
to
Don't forget the twit who put a
SAVE ALL
at the start of every subroutine.

Dick Hendrickson
0 new messages