1

I'm trying to create my own module of array (just for practicing). I wrote this module.

module myArray
    implicit none

    public set, get

    integer :: size = 5
    integer, allocatable :: array(:)
    allocate(array(size))
    
    contains

    subroutine set(index, value)
        implicit none
        integer, intent(in) :: index
        integer, intent(in) :: value
        array(index) = value
    end subroutine set
    
    function get(index) result(value)
        implicit none
        integer, intent(in) :: index
        integer :: value
        value = array(index)
    end function get

end module myArray

But I get this error

mymod.f90:8:25:

    8 |     allocate(array(size))
      |                         1
Error: Unexpected ALLOCATE statement in MODULE at (1)

What should I do to correct this?

Ruthvik
  • 790
  • 5
  • 28

2 Answers2

2

The idea is right but you're placing global data in a module, it won't be usable in the real world. You want to define a class for your array type. In fortran, you define a derived type binding both data and methods:

module myArrays
   implicit none

   type, public :: myArray
      
      ! Data here
      integer :: n = 0
      integer, allocatable :: array(:)
      
      contains
         ! Type-bound procedures here
         procedure :: set
         procedure :: get
         procedure :: new
   end type myArray 

contains

   elemental subroutine set(this,index,value)
      class(myArray), intent(inout) :: this
      integer, intent(in) :: index,value
      if (index>0 .and. index<=this%n) this%array(index) = value
   end subroutine set

   elemental integer function get(this, index) result(value)
      class(myArray), intent(in) :: this
      integer, intent(in) :: index
      if (index>0 .and. index<=this%n) then 
         value = this%array(index)
      else
         value = -huge(value) ! return an "invalid" value
      endif
   end function get

   elemental subroutine new(this, size)
      class(myArray), intent(inout) :: this
      integer, intent(in) :: size
      integer :: ierr

      ! This should go in a destructor routine
      this%n=0 
      deallocate(this%array,stat=ierr)

      ! Now allocate
      if (size>0) then 
         this%n=size
         allocate(this%array(Size),stat=ierr) 
      endif
   end subroutine new


end module myArrays

Note that you'll have to call the initializer routine new before using your array. Here's a program example:

program test_myArray
   use myArrays
   implicit none

   type(myArray) :: A,B

   call A%new(size=10)
   call B%new(size=20)

   print *, 'A size=',A%n,' B size=',B%n

end program
Federico Perini
  • 1,414
  • 8
  • 13
  • This kind of approach can be found in many papers about OOP in Fortran (90 or 95 at that time). Unfortunately, they still appear high in some searches. – Vladimir F Героям слава May 29 '22 at 05:57
  • I don't think this answer addresses the conceptual misunderstanding in the question (executable statements in the specification part of a module). Also, contrary to the assertion in the first paragraph, global data is stuck in a module all the time in the real world. Whether a wrapper is useful is a subjective question that depends on detail not touched by the question - the example implementation of such a wrapper is also a bit odd. – IanH May 29 '22 at 19:35
0

You cannot put executable statements directly into a module. You have to create a subroutine, put the statements into the subroutine and then call the subroutine in some way.

  • I did that but it shows some linker error – Ruthvik May 28 '22 at 14:41
  • 1
    Please, without telling us *exactly* the error and showing us *exactly* the code that generates that error it is very difficult to help. – Ian Bush May 28 '22 at 15:16
  • Linker errors could be caused by many things. Probably some additional coding error you made. We have a dedicated questions with several answers about linker errors https://stackoverflow.com/questions/66855252/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix – Vladimir F Героям слава May 28 '22 at 16:45