Gfortran mostly says this is not present, but sometimes it does evaluate to true. Intel seems to always evaluate to true.
Passing an unallocated array does seem to always evaluate to false, on both gfortran and Intel compilers. Passing an allocatable array that’s zero-sized does seem to evaluate to true for both compilers. It seems to only be zero-sized literal arrays and unallocated arrays that have issues.
Here’s a godbolt reproducer to have a play around with:
Does anybody know what the standard says here? This definitely feels like a bug to me.
Looks like a gfortran bug. According to the F2018 standard interpretation document (J3/18-007r1), section 15.5.2.12 it should be “present”, no matter whether zero or non-zero sized.
Interestingly (regarding your snippet on goldbolt.org), the presence of an unallocated array being passed as an optional argument depends on whether the dummy optional arg has allocatable attribute. If it does have it, the argument is considered as present, otherwise non-present.
program main
real, allocatable :: t(:)
print *, allocated(t)
call print_present("Unallocated, allocatable dummy", opt1=t)
call print_present("Unallocated", opt2=t)
contains
subroutine print_present(name, opt1, opt2)
implicit none
real, intent(in), dimension(:), allocatable, optional :: opt1
real, intent(in), dimension(:), optional :: opt2
character(len=*), intent(in) :: name
print*,name, present(opt1), present(opt2)
end subroutine print_present
end program main
gives
F
Unallocated, allocatable dummy T F
Unallocated F F
Well that is a bit of a pain with the unallocated variables, because it also means type information is not passed along, or you need another overload to make the dummy argument allocatable. I’m not sure that that is a good feature.
Looks like the zero-sized literal is definitely a bug though, thanks! I’ll report it to gfortran.