Associate construct with selector having a pointer

Associate construct with selector having a pointer

Consider the following code

program assoc_ptr

   integer, pointer :: p, q, r

   allocate(p)
   allocate(q)
   p = 1
   q = 2

   associate(x => p, y => q)
      print *, x, y

      q => p
      y = 5
      q = 6
      print *, x, y

      allocate(r)
      deallocate(p)
      p => r
      x = 3
      p = 4
      print *, x, y
   end associate

end program assoc_ptr

Is this allowed and standard-conformant? My gut-feeling is that this is simply wrong code. With ifort (19 beta, with and without optimisation) the output is:

           1           2
           6           5
           3           5

So in both cases, the association of y with q and of x with p are lost. In general this should lead to a SEGFAULT in more complex cases. Nevertheless, this looks like a bad pitfall if pointers are buried within complex derived types whose components might be reallocated in some subroutines...

publicaciones de 7 / 0 nuevos
Último envío
Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.

Yes, this is tricky, but the association is not lost. When you print out x and y, you print out the target of the pointer. The target of the pointer x in the final step is 3 because of the statement x = 3 above, and the target of y has not changed from 5 since line 14. 

In this example, x and y are not pointers. Associate names do not have the pointer attribute. The wording on this has changed a bit from F2008 to make it clearer, so I will quote from the F2018 draft:

The associating entity does not have the ALLOCATABLE or POINTER attributes; it has the TARGET attribute if and only if the selector is a variable and has either the TARGET or POINTER attribute.

 

Steve (aka "Doctor Fortran") - Retired from Intel

Quote:

Juergen R. wrote:

Yes, this is tricky, but the association is not lost. When you print out x and y, you print out the target of the pointer. The target of the pointer x in the final step is 3 because of the statement x = 3 above, and the target of y has not changed from 5 since line 14. 

I am not sure whether I understand you correctly. In my opinion x is still associated with what p has been before it was reallocated, but this is lost. So with x=3 I write into an illegal memory address.

Anyway, in the past I have used pointers and was not happy with this kind of pitfalls. But pointers are kind of dangerous. Now that I can use associate, I was hoping that such mistake are not possible, or at least can be recognised at compile-time. But it looks like, even so x and y are not pointers, that it seems best to still think of them as pointers. Probably they are implemented that way (with temporaries if association is with an expression.

No, they are not pointers. 

Steve (aka "Doctor Fortran") - Retired from Intel

Quote:

Steve Lionel (Ret.) wrote:

No, they are not pointers. 


That's what I wrote. But in some respect, which are relevant in the context of my short example, it becomes visible that internally they are implemented by pointers and behave somewhat like pointers. So without thinking of them as pointers it might become difficult to understand what's going wrong in cases like the code sample above.

So, is there a way to avoid (or at least easily find) this kind of bug?

Ok, I see what you're getting at. Essentially this is the same as having two pointers to an object, deallocating one pointer and referencing the other. When the first is deallocated, the second one becomes undefined (by the language rules), but there's no obvious way in Intel Fortran to detect this.

Steve (aka "Doctor Fortran") - Retired from Intel

Deje un comentario

Por favor inicie sesión para agregar un comentario. ¿No es socio? Únase ya