It seems to be allowed to declare derived types within the specification-part of a subroutine (or function for that matter) and use this type for local variables. However, if I add type-bound procedures to the derived type, I do not know how to provide an implementation for these methods. Putting it into the contains section does not seem to be allowed. Is having a derived type with type-bound procedures not allowed or do I need to implement it differently. I did not find anything on that topic in a couple of fortran books.
Here is a small example code, of what is not compiling, but it should convey the idea. Once the two lines marked by ' ! comment out' are commented out or removed, it compiles and works as expected).
module modderived implicit none private public sub contains subroutine sub(x) integer :: x type :: t integer :: x contains procedure :: w => sub_w ! comment out end type t type(t) :: tt print *, 'here: ', x tt%x = x call tt%w(4) ! comment out contains subroutine sub_w(self, y) class(t) :: self integer :: y print *, 'there: ', self%x + y end subroutine sub_w end subroutine sub end module modderived
The nagfor compiler gives you the following error message:
Error: sub_sub.f90, line 27: Type-bound procedure SUB_W must be a module procedure or external procedure with an explicit interface
detected at SUB_W@(
I don't have time to dig out the corresponding places in the standard right now, but that pretty much tells you where a TBP can be and where not.
Well, ifort gives more or less the same message. But here is the problem: I cannot place sub_w in the contains body of the module, as the type t would be out of scope. From this message I deduced that I either missed some possibility how to implement this, or that this part of the standard prevents defining derived types with type-bound procedure within subroutines or functions.
The constraint in Fortran 2008 is C465, which has words similar to the NAG compiler error.
You can declare derived types with type bound procedures within the specification part of a subroutine or function, you just can't have any bindings that take a passed argument.
Thanks for the clarification. This restriction (nopass) seems a bit strange, though.
(In the application I had in mind, t would extend an abstract class serving as a template and just implement one missing piece. As the extension t would only have local meaning within the subroutine, I had in mind to place it just there. But with the nopass restriction I will have to do that at the module level.)
Guessing a bit, but internal procedures can access the variables that correspond to their host instance, and there can be multiple instances of a procedure active (consider recursive calls). The ability to access variables of a particular host instance requires some additional work for an internal procedure call. The constraint avoids the intersection of that additional work with the machinery associated with dynamic resolution of specific bindings.
(Or perhaps that intersection isn't problematic, but keeping things simple seemed like a good idea at the time.)