I would like to write a procedure which takes an optional
argument, which may be of type FooType
or of type BarType
, such that this program is valid:
module m
implicit none
type :: FooType
end type
type :: BarType
end type
end module
program mwe
use m
implicit none
type(FooType), allocatable :: foo(:)
type(BarType), allocatable :: bar(:)
call func()
call func([FooType()])
call func([BarType()])
call func(foo)
call func(bar)
end program
My current attempt is:
module m
implicit none
type :: FooType
end type
type :: BarType
end type
interface func
module procedure func_FooType
module procedure func_BarType
end interface
contains
subroutine func_FooType(input)
type(FooType), intent(in), optional :: input(:)
write(*,*) 'foo'
end subroutine
subroutine func_BarType(input)
type(BarType), intent(in) :: input(:)
write(*,*) 'bar'
end subroutine
end module
But this does not work. Compiling with either gfortran 10.1.0
or ifort 2021.1
gives the output
foo
foo
bar
foo
bar
The problem is the final call, to func(bar)
. bar
is not allocated
, and so if it were passed to an optional
argument it would not be present
. However, the procedure which gets called is func_BarType
, which believes its input
is not optional
, and so has no way of checking if input
is present
. Indeed, if I change the input
to be a scalar not an array, the call to func(bar)
crashes at runtime under gfortran.