Optional passed-object dummy arguments
Example discussed here: https://fortran-lang.discourse.group/t/what-is-benefit-of-pass-in-type-bound-procedures/9294/8
! Can we use an optional passed-object dummy argument
! before the dynamic type has been established?
module m
type :: foo
contains
procedure, pass, non_overridable :: check
end type
contains
subroutine check(f)
class(foo), optional :: f
if (present(f)) then
print *, "present"
else
print *, "not present"
end if
end subroutine
end module
use m
type(foo), allocatable :: f
class(foo), allocatable :: g
call f%check
allocate(f)
call f%check
call g%check
allocate(foo :: g)
call g%check
end
And what is the problem with that?
Never mind, I tried it with all compilers, and only two get it right. What's really weird are the two compilers that print present for every call.
I guess I don't have access to those two that think it's always present. But I like the interpretation of the two that get it right. :)
I guess I don't have access to those two that think it's always present. But I like the interpretation of the two that get it right. :)
I don't like to name or shame Fortran compilers with bugs -- implementing this language is very difficult and nobody gets it right all of the time. So you'll have to find them yourself. But yes, a bad result from PRESENT seems to be even worse than crashing.
I've been pointed to the fact, the program is actually illegal, due to Section 15.5.1, paragraph 2,
The data-ref in a procedure-designator shall not be an unallocated allocatable variable or a pointer that is not associated.
That only affects whether the program is conformant with a document.
In case it's not clear, the point of this example (at least to me) is that the procedure binding has been declared NON_OVERRIDABLE, so the procedure can be resolved at compilation time without the use of any dynamic procedure table lookup. Compilers that don't do this are missing an easy and significant optimization.
That is also how I envisioned it. If the order is changed to:
allocate(f)
call f%check
allocate(foo :: g)
call g%check
the compilers I have access to work as I'd expect. But the Fortran document seems to imply that the data reference (i.e. f and g) must be allocated before it is valid to call any type-bound procedure, even non_overridable ones. The fact the passed-object dummy argument is optional seems to play no role then. There is also the question then if options like -C=pointer (NAG) or -fcheck=pointer (gfortran) are able to detect this fringe case.