# Unassociated/unallocated variable interpreted as a non present optional argument is misleading

**URL:** <https://fortran-lang.discourse.group/t/unassociated-unallocated-variable-interpreted-as-a-non-present-optional-argument-is-misleading/11072>\
**Category:** Uncategorized\
**Created:** [August 28, 2026, 2:23pm UTC](https://fortran-lang.discourse.group/t/unassociated-unallocated-variable-interpreted-as-a-non-present-optional-argument-is-misleading/11072 "2026-08-28T14:23:52Z")\
**Posts on this page:** 7\
**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:** [August 28, 2026, 2:23pm UTC](https://fortran-lang.discourse.group/t/unassociated-unallocated-variable-interpreted-as-a-non-present-optional-argument-is-misleading/11072/1 "2026-08-28T14:23:52Z")

</div>

The feature that makes an unassociated/unallocated variable interpreted as a non present optional argument looks nice (and I have used it on purpose in the past), but recently I encountered a case where it was misleading. Like this:

```auto
real, pointer :: a(:)

call foo(a)

contains
   subroutine foo(x)
      real, intent(in), optional :: x(:)
      
      if (present(x)) then
         ! do something
      else 
         ! do something else
      end if
   end subroutine
end

```

I forgot to associate the pointer `a(:)` before calling `foo(a)`, and as a result the subroutine was silently doing “something else” instead of the expected “something”… It took me a while to detect the problem, because the code is 100% valid…

Note that replacing the routine with 2 variants (one without the dummy argument and one with the mandatory dummy argument instead of optional) under a generic interface makes the code illegal if `a(:)` is unassociated/unallocated (and it can be trapped with a runtime check).

---

<div class="post-metadata">

**Author:** ![jwmwalrus](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/jwmwalrus/32/4483_2.png) [@jwmwalrus](https://fortran-lang.discourse.group/u/jwmwalrus)\
**Post date:** [August 28, 2026, 2:44pm UTC](https://fortran-lang.discourse.group/t/unassociated-unallocated-variable-interpreted-as-a-non-present-optional-argument-is-misleading/11072/2 "2026-08-28T14:44:45Z")

</div>

> [@PierU](#):
>
> I forgot to associate the pointer `a(:)` before calling `foo(a)`, and as a result the subroutine was silently doing “something else” instead of the expected “something”…

Hmm… if the actual argument is not allocated or not associated, then the subroutine cannot really do anything valid with it, can it?

If you explicitly state that the dummy argument is a pointer, that’s a different thing:

```fortran
real, pointer :: a(:)

call foo(a)

contains
   subroutine foo(x)
      real, intent(in), pointer, optional :: x(:)

      if (present(x)) then
         ! do something
          print*,'pointer is present'
      else 
         ! do something else
      end if
   end subroutine
end

```

```bash
$ ifort -diag-disable=10448 optional_ptr.f90 && ./a.out 
 pointer is present

```

Even with CONTAINed procedures, it sometimes helps to think of them as being separate or provided by a third-party —i.e., it’s not the subroutine’s fault that you forgot to associate `a(:)`.

---

<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:** [August 28, 2026, 3:41pm UTC](https://fortran-lang.discourse.group/t/unassociated-unallocated-variable-interpreted-as-a-non-present-optional-argument-is-misleading/11072/3 "2026-08-28T15:41:53Z")

</div>

> [@jwmwalrus](#):
>
> Hmm… if the actual argument is not allocated or not associated, then the subroutine cannot really do anything valid with it, can it?

This code is an over-simplification of my real code 🙂 , just to make the point…

> [@jwmwalrus](#):
>
> If you explicitly state that the dummy argument is a pointer, that’s a different thing:

Sure, but you don’t necessarily want to restrict the actual argument to a pointer…

> [@jwmwalrus](#):
>
> it’s not the subroutine’s fault that you forgot to associate `a(:)`

I know! My mistake, for sure… But my point is that this feature can be misleading when not used on purpose…

---

<div class="post-metadata">

**Author:** ![jwmwalrus](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/jwmwalrus/32/4483_2.png) [@jwmwalrus](https://fortran-lang.discourse.group/u/jwmwalrus)\
**Post date:** [August 28, 2026, 3:57pm UTC](https://fortran-lang.discourse.group/t/unassociated-unallocated-variable-interpreted-as-a-non-present-optional-argument-is-misleading/11072/4 "2026-08-28T15:57:37Z")

</div>

I think the issue is that some unintended behavior that’s beyond the reach of the standard, could really benefit from a language server (or a compiler’s `--syntax` flag in pedantic mode).

The list could include:

- Passed non-associated/unallocated to non-pointer/non-allocatable optional dummy argument.
- Reallocated derived type array instance with (now dangling) pointer components.
- …

---

<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:** [August 28, 2026, 6:37pm UTC](https://fortran-lang.discourse.group/t/unassociated-unallocated-variable-interpreted-as-a-non-present-optional-argument-is-misleading/11072/5 "2026-08-28T18:37:10Z")

</div>

> [@PierU](#):
>
> […] because the code is 100% valid […]

This is exploring some of the dark corners of the language. In your posted code, I think the behavior is undefined because the actual argument is in an undefined state. Changing the code to

```auto
real, pointer :: a(:) => null()

```

or adding

```auto
nullify(a)

```

will make it conforming. Of course, your actual code might not have this issue, so maybe this has nothing to do with solving your actual problem.

> [@PierU](#):
>
> Sure, but you don’t necessarily want to restrict the actual argument to a pointer…

This is yet another dark corner of the language. The combination of `intent(in), pointer` is allowed for a dummy argument even if the actual argument is not a pointer. It is a shortcut for declaring the dummy argument as target, declaring a local pointer, and assigning that local pointer to the target.

```auto
real, intent(in), target :: dummy(:)
real, pointer :: x(:)
x => dummy

```

However, I’m unsure what, if anything, the addition of the `optional` attribute does in this special case. Presumably the programmer can test if `present()` and pointer assign `x(:)` to something else? I might even say this is an obscure part of a dark corner.

> [@PierU](#):
>
> But my point is that this feature can be misleading when not used on purpose…

Yes, I agree with this. It is like implicit save. The semantics of these dark corners of the language is difficult to keep straight. They add only a little functionality to the language (or none at all), but they cause problems when they are used intentionally in an incorrect way or when they are stumbled upon unintentionally. To be honest, I’m not 100% sure that what I said above is correct, and it would take me an hour or so to look through the standard to check all of the cross references to make sure. So let me just say I **think** what I said above is right, and hopefully someone will correct me if I’m wrong.

---

<div class="post-metadata">

**Author:** ![davidpfister](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/davidpfister/32/3949_2.png) [@davidpfister](https://fortran-lang.discourse.group/u/davidpfister)\
**Post date:** [August 28, 2026, 6:42pm UTC](https://fortran-lang.discourse.group/t/unassociated-unallocated-variable-interpreted-as-a-non-present-optional-argument-is-misleading/11072/6 "2026-08-28T18:42:43Z")

</div>

It has one nice consequence, though. You can write a safe-size function like this

```fortran
pure integer function safe_size(x) result(res)
class(*), dimension(..), intent(in), optional :: x
res = -1
if (present(x)) res = size(x)
end function

```

---

<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:** [August 28, 2026, 6:54pm UTC](https://fortran-lang.discourse.group/t/unassociated-unallocated-variable-interpreted-as-a-non-present-optional-argument-is-misleading/11072/7 "2026-08-28T18:54:37Z")

</div>

> [@davidpfister](#):
>
> […] You can write a safe `size` function like this […]

I think also in this case the actual argument must be in a defined state in order for `present()` to work correctly on the dummy argument.
