# Is pointing to a target dummy argument safe after return?

**URL:** <https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199>\
**Category:** Help\
**Created:** [February 13, 2023, 3:57pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199 "2023-02-13T15:57:18Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [February 13, 2023, 3:57pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/1 "2023-02-13T15:57:18Z")

</div>

The simplest case:

```auto
call foo(a,p)

subroutine foo(aa,pp)
implicit none
real, intent(in), target :: aa(:)
real, pointer :: pp(:)
pp => aa
end subroutine

```

Is the actual pointer `p` guaranteed to point to the actual array `a` after the call to `foo()`? I would say no, in case there is some copy-in for `aa` (unlikely in practice, but not impossible)

---

<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:** [February 13, 2023, 4:30pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/2 "2023-02-13T16:30:04Z")

</div>

> [@PierU](#):
>
> Is the actual pointer `p` guaranteed to point to the actual array `a` after the call to `foo()`?

The standard only provides usable interpretation for the case where the actual argument `a` has the `TARGET` attribute. But there is no means to enforce that, thus the usage has potential pitfalls.

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [February 13, 2023, 4:41pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/3 "2023-02-13T16:41:43Z")

</div>

In my case, the actual argument has indeed the `target` attribute. So you mean that in this case it is supposed to be safe (which means that the compiler is not authorized to make a copy-in)?

---

<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:** [February 13, 2023, 5:14pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/4 "2023-02-13T17:14:14Z")

</div>

My understanding is the standard mostly takes a soft-influence - advisory - stance on such aspects, not just this one, and extends considerable leeway to the processors.

Given your concern with `copy-in`, I suggest the `CONTIGUOUS` attribute which will provide the compiler as well as the programmer with additional requirements and further safety i.e., assuming the data are contiguous in your actual use case:

```fortran
subroutine foo(aa,pp)
   real, intent(in), contiguous, target :: aa(:)
   real, contiguous, pointer :: pp(:)
   .
end subroutine
```

---

<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:** [February 13, 2023, 5:29pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/5 "2023-02-13T17:29:41Z")

</div>

> [@PierU](#):
>
> In my case, the actual argument has indeed the `target` attribute. So you mean that in this case it is supposed to be safe (which means that the compiler is not authorized to make a copy-in)?

I think the answer is that yes, it is safe in this case. The returned pointer is required to point to the original data (assuming a statement like `pp=>aa` exists somewhere in your original code).

However, if you were to add `contiguous` attributes to the dummy argument, then I think this will require the compiler to make a temporary copy of the data if it is not originally contiguous, so in that case the returned pointer would not point to the original data. I think the compiler is required to warn you about the mismatch of attributes. Maybe others can clarify this point.

---

<div class="post-metadata">

**Author:** ![plevold](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/plevold/32/754_2.png) [@plevold](https://fortran-lang.discourse.group/u/plevold)\
**Post date:** [February 14, 2023, 6:53am UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/6 "2023-02-14T06:53:09Z")

</div>

Interesting question! I don’t know what the standard has to say on this, but at least ifort gives me an invalid pointer if I force a situation with copy-in:

Consider this example:

```fortran
program main
    implicit none

    integer, allocatable :: i(:)
    integer, allocatable :: indices(:)
    integer, pointer :: p(:)

    i = [1, 2, 3, 4, 5, 6]
    call sub(i, p)
    print *, loc(i(1))
    print *, loc(p(1))
    indices = [1, 2, 5]
    call sub(i(indices), p)
    print *, loc(p(1))
    print *, 'p(1) = ', p(1)

contains

    subroutine sub(x, p)
        integer, target, intent(in) :: x(:)
        integer, pointer, intent(out) :: p(:)

        p => x
    end subroutine
end program

```

Output from one run:

```auto
         2605282179200
         2605282179200
          913231050816
 p(1) = -1596982848

```

Now if I change `x` to `intent(inout)` the compiler wil complain:

```bash
main.f90(13): error #7710: An array section having a vector subscript is not permitted if dummy argument has intent [IN]OUT. [I]
    call sub(i(indices), p)
-------------^

```

Having the same requirement for dummy arguments with `target` would avoid the situation in the example above, but even that can easily be avoided by adding another layer between the copy-in and the pointer assignment where the dummy argument does not have the `target` attribute.

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [February 14, 2023, 7:56am UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/7 "2023-02-14T07:56:31Z")

</div>

@plevold I tried your code with gfortran, and the pointer remains valid, although it doesn’t point to the original data (it could not, anyway):

```auto
      140441710247104
      140441710247104
      140441710247152
 p(1) = 1

```

So it looks like at first that the pointer survived and still point to the copied-in data, but it’s quite unlikely that this data is valid: this is on the stack, and the stack has to be freed upon return as far as I know. I checked that by appending a few lines with another pointer tp you main code:

```auto
    call sub(i(indices), q)
    print *, loc(q(1))
    print *, 'p(1) = ', p(1)
    print *, 'q(1) = ', p(1)

```

And the whole code gives:

```auto
      140393777740992
      140393777740992
      140393777741040
 p(1) = 1
      140393777741040
 p(1) = 5
 q(1) = 5

```

So as expected, the area pointed by `p(:)` has been reused and overwritten during the second call to `sub`.

---

<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:** [February 14, 2023, 9:00am UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/8 "2023-02-14T09:00:59Z")

</div>

See also the discussion [Why/When is the `target` attribute part of the characterisics of a procedure](https://fortran-lang.discourse.group/t/why-when-is-the-target-attribute-part-of-the-characterisics-of-a-procedure/4826)

IMO, one should **never** use the `target` attribute for a dummy argument, **when** the pointer pointing to it is supposed to be valid after the scope had been left. It should work (in theory,) if the actual argument indeed has the `target` attribute (but only then!), but no compiler I know gives you any warning/error, if you actually forget to specify that attribute for the actual argument. So, sooner or later, it is bound to fail due to oversight (and it can be a mess to find the bug…)

I always specify the `pointer` attribute for the dummy argument in those cases, as all compilers I know will ensure that the actual argument has either the `pointer` or the `target` attribute. So you are safely pass back pointers to them as they are warranted to be valid also after the end of the scope and you won’t be hit by any copy-in/copy-out issues.

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [February 14, 2023, 10:28am UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/9 "2023-02-14T10:28:40Z")

</div>

> [@aradi](#):
>
> IMO, one should **never** use the `target` attribute for a dummy argument, **when** the pointer pointing to it is supposed to be valid after the scope had been left. **It should work (in theory,) if the actual argument indeed has the `target` attribute (but only then!)**, but no compiler I know gives you any warning/error, if you actually forget to specify that attribute for the actual argument. So, sooner or later, it is bound to fail due to oversight (and it can be a mess to find the bug…)

In the example of @plevold, having `target` specified on both the actual and the dummy arguments is not enough. It is fully understandable that it can not work in such a case where copy-in can not be avoided, but how can we be sure that it work when copy-in is not required?

Does someone has the part of the standard that ensures that?

> [@aradi](#):
>
> I always specify the `pointer` attribute for the dummy argument in those cases, as all compilers I know will ensure that the actual argument has either the `pointer` or the `target` attribute. So you are safely pass back pointers to them as they are warranted to be valid also after the end of the scope and you won’t be hit by any copy-in/copy-out issues.

I learnt something today, I didn’t know that a non pointer actual argument could be passed to a pointer dummy! I assume that there is some hidden casting here?

---

<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:** [February 14, 2023, 12:07pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/10 "2023-02-14T12:07:05Z")

</div>

> [@aradi](#):
>
> … I always specify the `pointer` attribute for the dummy argument in those cases, as all compilers I know will ensure that the actual argument has either the `pointer` or the `target` attribute. …

@aradi ,

You may want to clarify this works only when the received argument is `intent(in)`.

---

<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:** [February 14, 2023, 1:31pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/11 "2023-02-14T13:31:22Z")

</div>

> [@FortranFan](#):
>
> You may want to clarify this works only when the received argument is `intent(in)`

Yes, thank you, indeed I should have added, that it only works with `pointer, intent(in)` arguments. Fortunately (?) the `intent(in)` attribute of a pointer still allows the modification of the pointers target (as it only prohibits to change the pointer association itself), so that it is not really a constraint for most use cases.

---

<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:** [February 14, 2023, 1:37pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/12 "2023-02-14T13:37:46Z")

</div>

> [@PierU](#):
>
> n the example of @plevold, having `target` specified on both the actual and the dummy arguments is not enough. It is fully understandable that it can not work in such a case where copy-in can not be avoided, but how can we be sure that it work when copy-in is not required?
> 
> Does someone has the part of the standard that ensures that?

The problem is the vector subscript. Note C.10.4, point 2 in the F2018 standard says:

> When execution of a procedure completes, any pointer that remains defined and that is associated with a dummy  
> argument that has the TARGET attribute and is either a scalar or an assumed-shape array, remains associated  
> with the corresponding actual argument if the actual argument has the TARGET attribute and is not an array  
> section with a vector subscript.

And this is one more reason, not to use the `TARGET` attribute for dummy arguments, if you want to use the pointer to it outside of the scope. You might fail in several ways, and the compiler won’t help you. However, if you modify the code as shown below, you get a “safe” version, where the 2nd call triggers a compiler error (at least ifort and nag complain, gfortran 11.2 seems to let it pass, though).

```auto
program main
    implicit none

    integer, allocatable,target :: i(:) ! Note the TARGET attribute here
    integer, allocatable :: indices(:)
    integer, pointer :: p(:)

    i = [1, 2, 3, 4, 5, 6]
    call sub(i, p) ! Compiles without problem and using p is safe as it really points to i(:)
    indices = [1, 2, 5]
    call sub(i(indices), p) ! Fails to compile (using p would not be safe anyway)
    print *, 'p(1) = ', p(1)

contains

    subroutine sub(x, p)
        integer, pointer, intent(in) :: x(:) ! Note the POINTER attribute here
        integer, pointer, intent(out) :: p(:)

        p => x
    end subroutine
end program

```

---

<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:** [February 14, 2023, 1:52pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/13 "2023-02-14T13:52:56Z")

</div>

> [@aradi](#):
>
> … no compiler I know gives you any warning/error, if you actually forget to specify that attribute for the actual argument …

@certik, do you think `LFortran` can eventually consider alerting users in such a scenario if they seek that, perhaps in a pedantic mode?

---

<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:** [February 14, 2023, 2:48pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/14 "2023-02-14T14:48:54Z")

</div>

> [@plevold](#):
>
> ```auto
> call sub(i, p)
> print *, loc(i(1))
> 
> ```

I think this is printing 64-bit addresses with a 32-bit function. It is probably returning just the low-order 32 bits of the address. That may be sufficient for this discussion, but in general information is being lost. Instead, the correct solution is to use `c_loc(),` but the return type `c_ptr` must then use `transfer()` in order to print its value.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [February 14, 2023, 3:10pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/15 "2023-02-14T15:10:53Z")

</div>

> [@FortranFan](#):
>
> @certik, do you think `LFortran` can eventually consider alerting users in such a scenario if they seek that, perhaps in a pedantic mode?

Good point, I added it to the list here: [Create pedantic/strict mode · Issue #363 · lfortran/lfortran · GitHub](https://github.com/lfortran/lfortran/issues/363)

---

<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:** [February 14, 2023, 7:18pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/16 "2023-02-14T19:18:23Z")

</div>

> [@FortranFan](#):
>
> @certik, do you think `LFortran` can eventually consider alerting users in such a scenario if they seek that, perhaps in a pedantic mode?

@certik @FortranFan I think, it will be difficult to issue proper warnings / errors because most scenarios involving a dummy argument with a `target` attribute are standard conforming, so the compiler is not supposed to complain:

- Passing actual argument with `target` attribute: OK
- Passing actual argument without `target` attribute: OK
- Passing array with vector indices as actual argument: OK
- Associating pointers with the dummy argument and using them during the subroutine execution: OK for all possible actual arguments with or without `target` attribute.

The only scenario, which is dangerous and non standard-conforming is:

- Passing an actual argument _without_ the `target` attribute (or with vector subscripts) **and** using a pointer associated with the corresponding dummy (with the `target` attribute) after the subroutine has finished, as those pointers become undefined at that point.

But how do you want to catch this reliably at compile time? When you compile the routine, you don’t know, whether the actual argument will or will not have the `target` attribute. When you compile the caller, you don’t know, whether the routine you call will “store” a pointer associated with the dummy (e.g. by using the `save` attribute or storing it in a derived type instance variable, if it is a type bound procedure). You would have to compile caller and routine at the same time, in order to detect the dangerous case.

IMO, this is more a problem of the standard.One should probably simply declare pointers pointing to a dummy argument (or actually any object) with the `target` attribute undefined, once the scope of the declaration has finished. Without exceptions and with no dependency on what kind of dummy argument was passed. Then people would be forced to always use the `pointer` attribute for the dummy argument, if they wish to a use pointer beyond the lifetime of a subroutine. This would be didactically much clearer, would definitely cause less surprises and the right usage could be probably much easier detected at compile time.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [February 14, 2023, 7:30pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/17 "2023-02-14T19:30:48Z")

</div>

@aradi There are several possible solutions to this:

- Restrict the standard in “pedantic” mode, so that it is always 100% safe. This thread presented several such approaches.
- Track all pointers and notice when they become dangling, which is not a compile time error, but a runtime error, but at least you still get an error (in Debug mode) instead of a segfault.
- You can notice when the function stores the pointer which will still be alive when the function exits, and the compiler can keep track of this recursively, similar to the “pure” and “simple” attributes. If the function is not “pointer safe”, then the compiler could require the target attribute to be set for the argument.
- There is also an option to track lifetimes at compile time like Rust does, but automatically, however that’s still more of a research problem I suspect.

---

<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:** [February 14, 2023, 7:49pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/18 "2023-02-14T19:49:48Z")

</div>

> [@aradi](#):
>
> One should probably simply declare pointers pointing to a dummy argument (or actually any object) with the `target` attribute undefined, once the scope of the declaration has finished. Without exceptions and with no dependency on what kind of dummy argument was passed.

It seems like this would eliminate many legitimate uses for pointer assignments, while also, forcing programmers to use pointers more than they would otherwise. I personally prefer to avoid pointers as much as possible (e.g. using allocatables instead), so I would not like for the language to force me to go backwards in that respect.

---

<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:** [February 14, 2023, 8:30pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/19 "2023-02-14T20:30:26Z")

</div>

> [@RonShepard](#):
>
> It seems like this would eliminate many legitimate uses for pointer assignments, while also, forcing programmers to use pointers more than they would otherwise. I personally prefer to avoid pointers as much as possible (e.g. using allocatables instead), so I would not like for the language to force me to go backwards in that respect.

@RonShepard No, it would eliminate only one single currently allowed scenario, which happens if all following 3 conditions are met:

1. a pointer is associated with a dummy argument having the `target` attribute,
2. **and** this pointer is used after the subroutine which defined the dummy argument has finished,
3. **and** the passed actual argument has the `target` attribute.

This is a very special combination. It is also very error-prone, as forgetting to declare the `target` attribute for the passed actual argument (failing to meet condition 3 above) makes your code non-conforming according to the current standard.

Every other scenario would be valid (or invalid) exactly the same way, as it is now. It definitely won’t change in any way, how you use `allocatable` objects or allocated pointers.

Also, please note, that having a dummy argument with the `pointer, intent(in)` attribute does not force you to declare the `pointer` attribute for the passed actual argument. It is enough to declare the `target` attribute for the passed actual argument, so you still can pass in an `allocatable` object. So, there is absolutely no need to use pointers at the callers side.

---

<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:** [February 14, 2023, 8:55pm UTC](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199/20 "2023-02-14T20:55:26Z")

</div>

> [@certik](#):
>
> You can notice when the function stores the pointer which will still be alive when the function exits, and the compiler can keep track of this recursively, similar to the “pure” and “simple” attributes. If the function is not “pointer safe”, then the compiler could require the target attribute to be set for the argument.

@certik I like this idea a lot. That would effectively mean, that the routine signature becomes an additional property (similar to `pure` and `simple`), which can be tracked transitively. Edge cases might be hard to detect/decide though. (I could store the pointer in a module variable, but not use this module variable outside of this routine anywhere. I could pass it to a C-routine, etc.) But it is probably worth the effort and is the most robust one.

The runtime check is for sure possible, at least one compiler (NAG) does this already. (This is how I managed to realize and to get rid of the few `target`/`pointer` misuses in our code a few years ago…) The problem is, however, that if a library containing the subroutine with the `target` dummy is external and was compiled in production mode, you probably won’t be able catch the misuse with run-time checks, even if the caller itself is compiled in debug-mode.

[Next page](https://fortran-lang.discourse.group/t/is-pointing-to-a-target-dummy-argument-safe-after-return/5199.md?page=2)
