# Why/When is the \`target\` attribute part of the characterisics of a procedure

**URL:** <https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826>\
**Category:** Uncategorized\
**Created:** [November 29, 2022, 4:01pm UTC](https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826 "2022-11-29T16:01:35Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![aradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/aradi/32/3659_2.png) [@aradi](https://fortran-lang.discourse.group/u/aradi)\
**Post date:** [November 29, 2022, 4:01pm UTC](https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826/1 "2022-11-29T16:01:35Z")

</div>

Does anybody know, why (and when) the `target` attribute is part of the signature of a procedure? Is the call to a subroutine where a given dummy argument has the `target` attribute different from the call to a similar subroutine, where the `target` attribute is not present for that dummy argument?

The use case triggering my question is type extension, where an extending type overrides a type bound procedure. If the extending implementation needs a pointer to the class instance (e.g. because it wants to point to some components within the type), it can not add the `target` attribute to the dummy argument `this`, if it was not specified in the base type:

```auto
module typedefs
  implicit none

  type :: base_type
  contains
    procedure :: method => base_method
  end type base_type

  type, extends(base_type) :: extending_type
  contains
    procedure :: method => extending_method
    procedure :: helper_method => extending_helper_method
  end type extending_type

contains

  subroutine base_method(this)
    class(base_type), intent(in) :: this
  end subroutine base_method

  subroutine extending_method(this)
    !class(extending_type), target, intent(in) :: this ! <- fails to compile
    class(extending_type), intent(in) :: this ! <- this works, but needs workaround
    ! Workaround: we call a helper method, which then specifies the target attribute
    call this%helper_method()
  end subroutine extending_method

  subroutine extending_helper_method(this)
    class(extending_type), intent(in), target :: this ! <- Note the target attribute
  end subroutine extending_helper_method

end module typedefs

```

My questions are:

1. What is the rationale for not allowing to specify the `target` attribute in the overriding type bound procedure for the class instance argument?
2. Why is the workaround above allowed/working? If one is not allowed to make `this` a target in `extending_method`, why is it OK to make it a target in a helper routine then. I don’t understand how/why do the two cases differ.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [November 29, 2022, 4:57pm UTC](https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826/2 "2022-11-29T16:57:28Z")

</div>

TL;DR: it’s a technicality.

- `TARGET` is considered a `characteristic` of received arguments in procedures.
- That the argument characteristics must all match between an overriding procedure and the one being overridden is a technical requirement
- The standard has long permitted the extension where the effective argument need **not** have the `TARGET` attribute in a call to a procedure with an explicit interface where the corresponding received argument has the `TARGET` attribute.

Thus the compilers complain about 1 above but not 2, go figure!

---

<div class="post-metadata">

**Author:** ![aradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/aradi/32/3659_2.png) [@aradi](https://fortran-lang.discourse.group/u/aradi)\
**Post date:** [November 30, 2022, 10:41am UTC](https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826/3 "2022-11-30T10:41:06Z")

</div>

> [@FortranFan](#):
>
> The standard has long permitted the extension where the effective argument need **not** have the `TARGET` attribute in a call to a procedure with an explicit interface where the corresponding received argument has the `TARGET` attribute.

OK, thanks, it is good to know, that the “workaround” with the helper function is standard conforming at least. Still, I am still wondering, **why** the `target` attribute is part of the characteristic of a procedure at all?

When a procedure declaring a dummy argument with the `target` attribute is called, there are two possibilities:

- The caller passes an actual argument _with_ the `target`/`pointer` attribute. If I understand it correctly now, in this case all pointers associated with the dummy argument will remain valid also after the exit from the procedure (and will be associated with the actual argument).

- The caller passes an actual argument _without_ the `target`/`pointer` attribute. In this case, all pointers associated with the dummy argument will become invalid after the exit from the procedure.

So, if I understand correctly, a procedure can never safely assume, that pointers it associates with a dummy argument with the `target` attribute remain valid after the exit, as it depends on how the procedure was called, which is beyond its control.

Therefore, in order to ensure deterministic behavior for all possible calls, a procedure should

- either specify the `target` attribute for a dummy argument, and then avoid to pass back or save any pointers it associates with that target (as the processor will not ensure, that the actual argument has the `target`/`pointer` attribute)

- or specify the `pointer` attribute for a dummy argument, as then all pointers associated with that dummy argument will remain valid after exit. (as the processor will enforce the caller to specify the `target` or the `pointer` attribute for the actual argument)

So, to me it seems, there are no scenarios, where in a robust programming model, the `target` attribute of a dummy argument should be used to anything else, as associating and using pointers to that argument **within the declaring procedure only**. So, it becomes an “internal affair” which the caller would not need to be aware of.

Do I overlook anything?

---

<div class="post-metadata">

**Author:** ![aradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/aradi/32/3659_2.png) [@aradi](https://fortran-lang.discourse.group/u/aradi)\
**Post date:** [November 30, 2022, 5:32pm UTC](https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826/4 "2022-11-30T17:32:03Z")

</div>

In a private conversation, my attention was pointed to 15.5.2.4 §9:

> If the **dummy argument has the TARGET attribute** , does not have the VALUE attribute, and either the effective  
> argument is simply contiguous or the dummy argument is scalar, assumed-rank, or assumed-shape, and does not  
> have the CONTIGUOUS attribute, and the **effective argument has the TARGET attribute** but is not a coindexed  
> object or an array section with a vector subscript then  
> • any pointers associated with the effective argument become associated with the corresponding dummy  
> argument on invocation of the procedure, and  
> • **when execution of the procedure completes, any pointers that do not become undefined (19.5.2.5) and are  
> associated with the dummy argument remain associated with the effective argument.**

The second bullet point (emphasis mine) seems to be indeed a reason for making the `TARGET` attribute of a dummy variable part of the intrinsic. However, I fail to see, how one could actually exploit this scenario in a real program.

Is there any way to find out within the procedure, whether the effective actual argument has the `TARGET` attribute? If not, wouldn’t relying on it result in very fragile code? (If the caller forgets to specify the `TARGET` attribute, the processor would not emit any compile-time errors/warnings, but the resulting code may behave indeterministic due to the usage of undefined pointers.) Wouldn’t it be more logical to drop the second bullet point, and just state, that pointers associated with a dummy argument with the `TARGET` attribute become generally undefined at exit? If one wanted to keep the validity of the pointers after exit from the procedure, one should define the `pointer` attribute for the dummy argument instead.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [November 30, 2022, 6:10pm UTC](https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826/5 "2022-11-30T18:10:55Z")

</div>

> [@aradi](#):
>
> Wouldn’t it be more logical to drop the second bullet point, and just state, that pointers associated with a dummy argument with the `TARGET` attribute become generally undefined at exit?

That would place some large restrictions on the valid use of pointers in the language. Sometimes you want to assign pointers to a target, and the best place to do that is in a subroutine rather than in the calling program.

> [@aradi](#):
>
> If one wanted to keep the validity of the pointers after exit from the procedure, one should define the `pointer` attribute for the dummy argument instead.

There are many advantages to using nonpointer entities in fortran. These include local variables declared in the usual way and allocatable variables. I personally prefer in my programming to avoid pointers as much as possible in favor of these other safer types of entities because you do not need to worry about dangling pointers and memory leaks, the language itself enforces the consistency – it removes them from the stack at the right time, it deallocates them at the right time, and so on. If instead you declare everything as anonymous memory and pointers, then you open yourself up to all kinds of mayhem.

---

<div class="post-metadata">

**Author:** ![aradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/aradi/32/3659_2.png) [@aradi](https://fortran-lang.discourse.group/u/aradi)\
**Post date:** [November 30, 2022, 7:51pm UTC](https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826/6 "2022-11-30T19:51:40Z")

</div>

@RonShepard No, I don’t want to apply any of those constraints! (I am actually using the `TARGET` attribute a lot. )

What I am suggesting is, to make the usage of the `TARGET` attribute more systematic, easier to understand and probably also easier to implement in compilers by suggesting the following rules:

- If one associates a pointer with a `TARGET` **dummy** argument within a procedure, the pointer shall always become undefined if the procedure is finished.

- The current exception (the one marked in the quote), which requires the associated pointer to remain valid after the end of the procedure if the actual argument had the `TARGET`attribute, should be deleted.

Rationale: The caller has two different ways of calling a procedure (by passing an actual argument with or without the `TARGET` attribute). Depending which of the two the caller has chosen, the behavior of the pointers associated with the dummy argument with the `TARGET` attribute will behave differently. But the callee has no way to tell, which of the behavior it should expect! So, currently the **behavior of a pointer associated within the procedure depends on something which the procedure can**

- **neither control** (compiler won’t be any help, as the `TARGET` attribute for the actual argument is not enforced)

- **nor check** , not even at run-time.

So, the only sensible choice in any program ever is to go for safety / determinism and always assume, that the pointers associated with the dummy argument with the `TARGET` attribute become undefined when leaving the procedure. And if you wish to keep the pointers to a dummy argument valid after the end of the procedure, the only safe way is to declare the `POINTER` attribute for the **dummy argument**. This would enforce a compiler check on the caller, as the actual argument must have then the `TARGET` or the `POINTER` attribute.

(And as a byproduct, if the exception above would be deleted, maybe one could also drop the `TARGET` attribute from the characteristic of a procedure, allowing for a more flexible usage without the need of an additional call as a workaround, as shown in the original example above.)

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [November 30, 2022, 9:48pm UTC](https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826/7 "2022-11-30T21:48:17Z")

</div>

> [@aradi](#):
>
> So, the only sensible choice in any program ever is to go for safety / determinism and always assume, that the pointers associated with the dummy argument with the `TARGET` attribute become undefined when leaving the procedure.

As I said previously, this would place significant constraints on the programmer’s ability to use pointers. Sometimes the best place to make the pointer assignment is in the subroutine, not in the calling program, so preventing the programmer from doing that would constrain the programmer, in addition to making a couple of decades of standard conforming code nonstandard.

> [@aradi](#):
>
> And if you wish to keep the pointers to a dummy argument valid after the end of the procedure, the only safe way is to declare the `POINTER` attribute for the **dummy argument**. This would enforce a compiler check on the caller, as the actual argument must have then the `TARGET` or the `POINTER` attribute.

If the dummy argument is declared pointer, then the actual argument must be a pointer. I don’t think there are any exceptions to that longstanding rule. If the dummy argument is not a pointer, then the actual argument can be a pointer or a non pointer variable.

When the actual argument has the target attribute, then that prevents the compiler from making a temporary copy during the calling sequence. That is what allows the pointers to remain associated after the subroutine return. Without that target attribute (or pointer attribute, and maybe some other similar situations), then the compiler is allowed to make temporary copies during the calling sequence. In this case, the pointer assignments in the subroutine are associated with that copy, not with the original array. That is why they become undefined after the subroutine call.

---

<div class="post-metadata">

**Author:** ![aradi](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/aradi/32/3659_2.png) [@aradi](https://fortran-lang.discourse.group/u/aradi)\
**Post date:** [November 30, 2022, 10:58pm UTC](https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826/8 "2022-11-30T22:58:40Z")

</div>

> [@RonShepard](#):
>
> If the dummy argument is declared pointer, then the actual argument must be a pointer. I don’t think there are any exceptions to that longstanding rule.

As of Fortran 2008, you can pass an actual argument with the `TARGET` attribute for a dummy argument with the `POINTER` attribute. So, if you declare the `POINTER` attribute for the dummy argument, the compiler will enforce, that the passed actual argument has either the `TARGET` or the `POINTER` attribute. And you can be sure, that the pointers associated within the procedure are still valid after exiting the procedure. (So you get the best of both worlds!) In contrast to a dummy argument with the `TARGET` attribute, where the compiler does not enforce anything on the caller side, and therefore, the called procedure can not know, whether the associate pointers will have any meaning after it finishes.

So, even if the standard won’t be modified, we should probably teach people to always use the `POINTER` attribute for a dummy argument, if they want to associate a pointer within the procedure with it, and the pointer should remain valid after the procedure finishes.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [December 1, 2022, 12:23am UTC](https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826/9 "2022-12-01T00:23:33Z")

</div>

> [@aradi](#):
>
> you can pass an actual argument with the `TARGET` attribute for a dummy argument with the `POINTER` attribute

The received argument in the procedure is required per the standard to have `INTENT(IN)` attribute if it has the `POINTER` and the effective argument has the `TARGET` attribute. This is the so-called `auto-targeting` feature.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [December 1, 2022, 8:23pm UTC](https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826/10 "2022-12-01T20:23:42Z")

</div>

> [@aradi](#):
>
> As of Fortran 2008, you can pass an actual argument with the `TARGET` attribute for a dummy argument with the `POINTER` attribute.

I stand corrected, I was not aware of this corner case. The pointer dummy must be INTENT(IN), which means the pointer association cannot be modified by the subroutine. It is basically a shorthand for a local pointer assignment to a target dummy, which is probably what I would write anyway just to make the code clear.
