Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Associate construct with selector having a pointer

Martin1
New Contributor I
270 Views

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...

0 Kudos
6 Replies
Juergen_R_R
Valued Contributor I
270 Views

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. 

0 Kudos
Steve_Lionel
Honored Contributor III
270 Views

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.

 

0 Kudos
Martin1
New Contributor I
270 Views

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.

0 Kudos
Steve_Lionel
Honored Contributor III
270 Views

No, they are not pointers. 

0 Kudos
Martin1
New Contributor I
270 Views
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?
0 Kudos
Steve_Lionel
Honored Contributor III
270 Views

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.

0 Kudos
Reply