# Passing \`allocatable, optional\` to \`optional\` argument

**URL:** <https://fortran-lang.discourse.group/t/passing-allocatable-optional-to-optional-argument/9736>\
**Category:** Uncategorized\
**Created:** [May 16, 2025, 7:41am UTC](https://fortran-lang.discourse.group/t/passing-allocatable-optional-to-optional-argument/9736 "2025-05-16T07:41:43Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![FedericoPerini](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/federicoperini/32/1750_2.png) [@FedericoPerini](https://fortran-lang.discourse.group/u/FedericoPerini)\
**Post date:** [May 16, 2025, 7:41am UTC](https://fortran-lang.discourse.group/t/passing-allocatable-optional-to-optional-argument/9736/1 "2025-05-16T07:41:44Z")

</div>

Consider [this example](https://godbolt.org/z/hE1sPYEaf) where we pass an `allocatable, optional` argument to call a `optional` argument:

- works with LFortran, Intel-Classic
- Fails (segfault) with gfortran, ifx, flang-new

My understanding of the standard is that in `opt_alloc` we should not have to check `present(i)`, because it is an optional argument to the procedure, despite the one more level of pointer dereferencing passing from `optional` to `allocatable, optional`. What is the standard-conforming behavior?

```auto
module options
   public 
   contains

   subroutine opt(i)
      integer, optional, intent(in) :: i
      print *, 'IS PRESENT? ',present(i)
   end subroutine opt 

   subroutine opt_alloc(i)
      integer, allocatable, optional, intent(in) :: i
      call opt(i)
   end subroutine opt_alloc 

end module options

program p
   use options
   integer, allocatable :: i

   call opt_alloc() ! Failure here
   call opt_alloc(i)
   allocate(i)
   call opt_alloc(i)

end program

```

---

<div class="post-metadata">

**Author:** ![MarDie](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mardie/32/54_2.png) [@MarDie](https://fortran-lang.discourse.group/u/MarDie)\
**Post date:** [May 16, 2025, 8:37am UTC](https://fortran-lang.discourse.group/t/passing-allocatable-optional-to-optional-argument/9736/2 "2025-05-16T08:37:31Z")

</div>

some aspects of this are discussed in [An unallocated variable passed as an argument is not PRESENT](https://fortran-lang.discourse.group/t/an-unallocated-variable-passed-as-an-argument-is-not-present/1724).

According to my understanding, the code is valid and in the first case the argument in `opt` is not present.

---

<div class="post-metadata">

**Author:** ![FedericoPerini](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/federicoperini/32/1750_2.png) [@FedericoPerini](https://fortran-lang.discourse.group/u/FedericoPerini)\
**Post date:** [May 16, 2025, 9:03am UTC](https://fortran-lang.discourse.group/t/passing-allocatable-optional-to-optional-argument/9736/3 "2025-05-16T09:03:09Z")

</div>

Reading [An unallocated variable passed as an argument is not PRESENT - #13 by billlong](https://fortran-lang.discourse.group/t/an-unallocated-variable-passed-as-an-argument-is-not-present/1724/13) I also interpret that the posted code should be conforming, because `i` from `opt_alloc` is the actual argument fed to `opt` and it is not only not allocated; also not present.

But of course assuming standard conformity, a compiler would have to handle the subtle address difference between `present(i) .and. .not.allocated(i)` and `.not.present(i)`

---

<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:** [May 16, 2025, 4:40pm UTC](https://fortran-lang.discourse.group/t/passing-allocatable-optional-to-optional-argument/9736/4 "2025-05-16T16:40:16Z")

</div>

Furthermore, what should it print? LFortran currently prints:

```auto
$ lfortran a.f90
IS PRESENT? F
IS PRESENT? F
IS PRESENT? T

```

Is this correct?

You can enhance the test like this:

```fortran
   subroutine opt(i)
      integer, optional, intent(in) :: i
      print *, 'Present in opt: ',present(i)
   end subroutine opt

   subroutine opt_alloc(i)
      integer, allocatable, optional, intent(in) :: i
      print *, 'Present in opt_alloc: ',present(i)
      call opt(i)
   end subroutine opt_alloc

```

Now LFortran prints:

```console
$ lfortran a.f90
Present in opt_alloc: F
Present in opt: F
Present in opt_alloc: T
Present in opt: F
Present in opt_alloc: T
Present in opt: T

```

---

<div class="post-metadata">

**Author:** ![FedericoPerini](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/federicoperini/32/1750_2.png) [@FedericoPerini](https://fortran-lang.discourse.group/u/FedericoPerini)\
**Post date:** [May 16, 2025, 5:21pm UTC](https://fortran-lang.discourse.group/t/passing-allocatable-optional-to-optional-argument/9736/5 "2025-05-16T17:21:53Z")

</div>

Yes, that’s exactly the answer I would expect! Another test would be with

```auto
   subroutine opt_ptr(i)
      integer, pointer, optional, intent(inout) :: i
      call opt(i)
   end subroutine opt_ptr

```

it has the same effect. My understanding is that a C equivalent would be:

```auto
void opt_alloc(int **i) {
    if (i) { // present
        opt(*i); 
    } else {
        opt(NULL); 
    }
}

```

so it really should be valid code, even safer with the allocatable that has _always_ a state (while a `pointer` may be undefined).
