Malcolm,

Thanks - this is certainly much more in lines of my expectations based upon my very amateurish understanding of what the compilers need to do under the hood.  (And did not have my F90 books with me where I was working yesterday.)

I have generally only used move_alloc() within the implementation of derived types with type-bound procedures, which should eliminate any possibility of clients having invalidated pointers.   I've found that I can write almost all of my code now without any pointers at all, much less mixed pointers/allocatable.    Needed it for a doubly-linked list yesterday.  (Or so I thought until I found that one of my compilers does not yet support "recursive" ALLOCATABLE components, so ended up needing a purely POINTER-based implementation.)

Cheers,

- Tom




On Feb 18, 2014, at 2:29 AM, Malcolm Cohen <[log in to unmask]> wrote:

No, this is not safe, in fact the program is not even valid.
 
The situation is clearly and explicitly described in MOVE_ALLOC:
  “If TO does not have the TARGET attribute, the pointer association status of any pointer associated with FROM on entry becomes undefined.”
this means that your pointer “k” is undefined, and therefore you are not permitted to reference it.
 
In practice, this may appear to “work” today but might not work tomorrow (even without recompilation).  More chance of going wrong with higher levels of optimisation, but some things will almost certainly produce obvious garbage regardless, such as overlapping assignments between j and k (especially skewed overlapping assignments).
 
Cheers,
 
From: [log in to unmask]" href="mailto:[log in to unmask]">Tom Clune
Sent: Tuesday, February 18, 2014 6:45 AM
To: [log in to unmask]" href="mailto:[log in to unmask]">[log in to unmask]
Subject: [COMP-FORTRAN-90] TARGET and move_alloc() ?
 
Consider the short program shown below.    After assigning the pointer "k" to the allocated integer array "i", move_alloc is used to transfer the data to "j".  It is clear that "i" must have the TARGET attribute, but I'm less certain whether the same is true of "j".    The code below "works" with all the compilers I have access to, but I cannot help but feel that I've created the possibility that the compiler is unaware of the aliasing between "j" and "k".   Is this safe?
 
integer, target, allocatable :: i(:)
integer, allocatable :: j(:)
integer, pointer :: k(:)
 
i = [1,2,3,4]
k => i
print*,'before: ', k
call move_alloc(from=i, to=j)
print*,'after: ', k
 
end
 
 


 

Thomas Clune, Ph. D.  <[log in to unmask]>
Chief, Software Systems Support Office Code 610.3
NASA GSFC 301-286-4635
MS 610.8 B33-C128 <http://ssso.gsfc.nasa.gov>
Greenbelt, MD 20771