Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29394 Discussions

Compiler error passing user-defined array to a subroutine

les_w_1
Beginner
1,103 Views

I'm having a Fortran 77 problem passing an allocated  user-defined Type array to a subroutine.  The subroutine compiles first without errors.  The calling program complains that the actual argument differs from the dummy argument.  The array has the same Type structure in both the sub and calling program. I'm using compiler v16.0.  I'd appreciate your help with this.  

Calling program:
          type bounds
             real*8::fromth=0d0,toth=0d0,fromph=0d0,toph=0d0
          end type
          type(bounds),dimension(:),allocatable::elbounds
          integer num
          num=100
          allocate (elbounds(num))
          call sub(num,elbounds)

Subroutine:
          subroutine sub(num,elbounds)
          integer num
          type bounds
             real*8::fromth=0d0,toth=0d0,fromph=0d0,toph=0d0
          end type
       type (bounds)::elbounds(num)   

0 Kudos
1 Solution
jimdempseyatthecove
Honored Contributor III
1,103 Views

Try this:

New module files:
           ! bounds_mod.f90
           module bounds_mod
             type bounds
              real*8::fromth=0d0,toth=0d0,fromph=0d0,toph=0d0
             end type
           end module bounds_mod
---------
           ! sub_interface.f90
           module sub_interface
             interface
             subroutine sub(num,elbounds)
               use bounds_mod
               integer num
               type (bounds)::elbounds(num)
             end subroutine sub  
             end interface
           end module sub_interface

Calling program:
           use bounds_mod
           use sub_interface
           type(bounds),dimension(:),allocatable::elbounds
           integer num
           num=100
           allocate (elbounds(num))
           call sub(num,elbounds)

Subroutine:
           subroutine sub(num,elbounds)
           use bounds_mod
           integer num
           type (bounds)::elbounds(num)  

Jim Dempsey

View solution in original post

0 Kudos
3 Replies
Steven_L_Intel1
Employee
1,103 Views

It's not the same type by the language rules, it's a different type with the same name. Put the type declaration in a module and USE the module instead of redefining the type.

And by the way, this is Fortran 90 code, not Fortran 77.

0 Kudos
mecej4
Honored Contributor III
1,103 Views

Two user-defined types are considered distinct if they have distinct definitions, even if they have components that match in type, order and size. Consider this example:

program xtypes
implicit none

type avec
     real x,y,z
end type

type bvec
     real x,y,z
end type

type(avec) :: u
type(bvec) :: v

u%x=10; u%y=12; u%z=15

v = u
write(*,'(3E12.3)')v%x,v%y,v%z
end program

The compiler says:

xtyp.f90(17): error #6197: An assignment of different structure types is invalid.   
v = u
----^
compilation aborted for xtyp.f90 (code 1)

One solution is to put the type definition in a module and USE that module instead of repeating the type definition in different subprograms. Another is to make the subroutine a contained subroutine, in which case the type is available by host association.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,104 Views

Try this:

New module files:
           ! bounds_mod.f90
           module bounds_mod
             type bounds
              real*8::fromth=0d0,toth=0d0,fromph=0d0,toph=0d0
             end type
           end module bounds_mod
---------
           ! sub_interface.f90
           module sub_interface
             interface
             subroutine sub(num,elbounds)
               use bounds_mod
               integer num
               type (bounds)::elbounds(num)
             end subroutine sub  
             end interface
           end module sub_interface

Calling program:
           use bounds_mod
           use sub_interface
           type(bounds),dimension(:),allocatable::elbounds
           integer num
           num=100
           allocate (elbounds(num))
           call sub(num,elbounds)

Subroutine:
           subroutine sub(num,elbounds)
           use bounds_mod
           integer num
           type (bounds)::elbounds(num)  

Jim Dempsey

0 Kudos
Reply