Could someone please tell me whether the following code is standards conformant, and if so why? I contend that both the declared and dynamic type of bar do not match the interface and thus the code should not compile or execute without error. But gfortran, intel, and nag all compile and execute this code without complaint. Is there something about interface matching and argument types that I’m not understanding?
module foo_m
implicit none
type :: foo_t
contains
procedure :: copy_into
end type
type, extends(foo_t) :: bar_t
end type
contains
subroutine copy_into(self, rhs)
class(foo_t), intent(inout) :: self
type(foo_t), intent(inout) :: rhs
end subroutine
end module
program main
use foo_m, only: foo_t, bar_t
implicit none
type(foo_t) :: foo
class(foo_t), allocatable :: bar
bar = bar_t()
call foo%copy_into(bar)
end program
A really interesting question that I don’t think I’d ever considered before. @pmk is correct. If you’re looking for places in the standard (F18), 15.5.2.4 p2 (key is “type compatible”) and 15.5.2.3 p3 (“associated with the declared type part of that actual argument”) seem to speak to your question.
Very interesting, but I have to agree with Brad that it is counterintuitive. What’s the point of having “class” if an argument declared as “type” works for children too (here, that is, I bet elsewhere it does not)? Is “class” only necessary for the “self” argument in a method?
Confusing as it may be, the standard, starting with the Fortran 2003 revision where support toward polymorphic types was introduced, has maintained in the section on CLASS where it explains what is type compatible:
“A nonpolymorphic entity is type compatible only with entities of the same declared type”.
The section on argument association of actual with dummy argument then refers to that section.
In the code in the original post, as explained upthread, the declared type of object bar matches that of the dummy argument and thus the code conforms.
Were the declaration to be class(bar_t), allocatable :: bar instead for example, the code will not conform.
Thank you all for the explanations and references to the standard. I’m not sure I understand why the standard is written to allow this, but at least now I’m aware of it.