Search code examples
fortranjagged-arraysallocatable-array

I wish to create Jagged arrays in Fortran but receives "There is no specific subroutine for the generic ‘new’ at (1)"


I wish to create jagged arrays in Fortran with multiple levels of allocation. However I run in to the error of "There is no specific subroutine for the generic ‘new’ at (1)" for both my constructor and destructor procedures.

I'm quite new at Fortran. I believe the problem is my 1st argument "M1" doesn't fit. However, I can't seem to figure out why.

module JaggedArrayModule
  implicit none
  save
  private
  public JaggedArray, New, Delete

  type JaggedArray
    private
    real, allocatable               :: vector(:)
  end type

  interface New
    module procedure NewMatrix
  end interface

  interface Delete
    module procedure DeleteMatrix
  end interface

contains

  subroutine NewMatrix(Matrix, maxsize)
    type (JaggedArray), intent(out), allocatable   :: Matrix(:)
    integer                                        :: maxsize, i

    allocate(Matrix(maxsize))
    do i=1, maxsize
      allocate(Matrix(i)%vector(i))
    enddo
  end subroutine

  subroutine DeleteMatrix(Matrix, maxsize)
    type (JaggedArray), intent(inout), allocatable :: Matrix(:)
    integer                                        :: maxsize, i    

    do i=1, maxsize
      deallocate(Matrix(i)%vector(i))
    enddo
    deallocate(Matrix)   
  end subroutine

end module



program main
use JaggedArrayModule
type (JaggedArray) :: M1(5)

call New(M1, 10)
call Delete(M1, 10)


end program

Solution

  • In these case the best way to debug the error message is to call the actual specific subroutine. That means to call NewMatrix instead of Matrix.

    Then you will get

     call NewMatrix(M1, 10)
                   1
    Error: Actual argument for ‘matrix’ must be ALLOCATABLE at (1)
    jagged.f90:51:18:
    
     call DeleteMatrix(M1, 10)
                      1
    Error: Actual argument for ‘matrix’ must be ALLOCATABLE at (1)
    

    That is pretty much self-explanatory. M1 must be allocatable to be passed to a subroutine that has an allocatable dummy argument. In modern Fortran generic disambiguation also considers the allocatable attribute. That is why you get the original error message.


    Be aware that I get also this error for your code:

    jagged.f90:37:17:
    
           deallocate(Matrix(i)%vector(i))
                     1
    Error: Allocate-object at (1) must be ALLOCATABLE or a POINTER
    

    You should use just

    deallocate(Matrix(i)%vector)
    

    However, the allocatable components are deallocated automatically. There is no need for a specialized (finalization) subroutine that does that.

    The allocate statement

    allocate(Matrix(i)%vector(i))
    

    also probably wants some other size, and not i, but only you know that.