Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
79 Views

target and pointer association

If you associate a pointer with a target in one scope (say a subroutine), and then use both in another subroutine, do you need to declare the dummy argument corresponding to the target with "target" attribute? In other words: real :: a(10) real, pointer :: pa(:) ... subroutine assoc(x,px) real, target, intent(in) :: x(10) real, pointer, intent(out) :: px(:) px=>x end subroutine assoc subroutine bingo(x,px) real, intent(inout) :: x(10) !should I declare x as "target" ? real, intent(inout) :: px(:) px=x+1 end subroutine bingo .... call assoc(a,pa) ... ... ... call bingo(a,pa)
0 Kudos
6 Replies
Highlighted
Employee
79 Views

The earlier discussion here is helpful in explaining the need/use of TARGET for the dummy argument.

From my understanding, for the code that is outlined, TARGET is not needed in the scope of bingo() because the assignment is not a pointer assignment but instead an array assignment.

The Doctor's discussions below are also helpful:

Doctor Fortran in "I've Come Here For An Argument"
Doctor Fortran in "I've Come Here For An Argument, Side 2"

0 Kudos
Highlighted
79 Views

It should be noted that the call to assoc creates a permitted alias between a and pa, the subsequent call to bingo, assuming pa is not reassociated or nullified, presents aliases to the call of bingo. This is in violation of FORTRAN calling rules.

Jim Dempsey

0 Kudos
Highlighted
Beginner
79 Views

Thanks for the answers.

My takeaway is:

* the critical point (why we need the TARGET attribute) is the pointer association itself; so, if we delegate the pointer association (=>, or c_f_pointer, ...) to an "association subroutine" and decorate the target with TARGET, the behaviour of the pointer and its target outside that subroutine is as if both are one and the same thing (unless we reassociate the pointer, or nullify it) and there is nothing fishy that can happen behind the scenes ...

 

* ... except if, subsequent to the association, they both are passed to some subroutine as distinct dummy arguments which leads to "argument aliasing" that violates the Fortran calling rules (can't be caught by a compiler) and may lead to unpredictable (read *wrong*) results

 

Of course, the hidden agenda behind the original question is: can i move TARGET from top-level into specific, "association" subprograms where the association happens, so that the compiler can optimize the expressions involving the "targeted" arrays and their pointers unhindered by a global TARGET attribute outside of the association subprograms?

0 Kudos
Highlighted
79 Views

Consider:

subroutine bingo(x,px)
 real, intent(inout), target :: x(10) !should I declare x as "target" ?
 real, intent(inout), pointer :: px(:)

Where px is not reassociated within bingo. The FORTRAN calling convention (from my understanding) states that on the call, x and px cannot be aliases to each other (in part or in whole). However, within the call, px may be re-associated to some/all of x. Note, up to the point of reassociation, the non-alias rule applies. IOW, in your use, re-association is not performed. Call with aliased references is "undefined" behavior. IOW may work as intended at times, may not work as intended at other times.

Perhaps IanH can pipe in here, as he appears to be most familiar with the FORTRAN specification.

Jim Dempsey

0 Kudos
Highlighted
Black Belt
79 Views

I agree with Jim's comment in #3 - the code in #1 would violate the argument aliasing rules.

Dummy arguments can be aliased with each other and still be defined if all the relevant dummy arguments have the TARGET attribute (plus some other requirements not relevant here - see F2008 12.5.2.13 for details).  bingo in #1 would need TARGET on both x and px, while bingo in #5 is ok (noting that if a pointer is correctly associated with something, then that something already has the TARGET attribute).

The code in #1 also references a undefined pointer, as explained in the links in #2.  If an actual argument without the TARGET attribute is argument associated with a dummy argument with the TARGET attribute (as for `a` in the call to `assoc`), then when the procedure completes, any pointers associated with the dummy argument become undefined when the procedure completes (12.5.2.4p12).  So `px` becomes undefined when bingo completes, which means that `pa` in the calling scope becomes undefined - references to that pointer later on are then problematic.

You cannot "move" the TARGET attribute in this way.

The ability for variables to inadvertently lose the TARGET attribute, and make pointers that should be otherwise associated with those variables become undefined, is a latent issue with the language, mitigated to some extent by the F2008 "auto-targeting" feature.  I am not sure if current ifort supports this or not - but with appropriate support, you would declare the `x` dummy argument of assoc to be an INTENT(IN), POINTER, the compiler will then diagnose attempts to use an actual argument that does not have the POINTER or TARGET attribute, if the actual argument is a TARGET, then the pointer dummy is automatically associated with it.  (An INTENT specification on a POINTER dummy relates to the pointer association status of the pointer, and not the value of the thing that the pointer might be associated with.)

0 Kudos
Highlighted
Beginner
79 Views

Wow, thanks Ian, Jim and Kevin. Those were some really insightful answers. So, wherever the pointer and the target are present in the same scope, that target needs the TARGET attribute.

0 Kudos