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

allocatable dummy arguments with CLASS keyword

Alexis_R_
New Contributor I
972 Views
In the example below, I would like to have sub1 work on argument of type type1 or any other type which extends type1, e.g. type2.
However,
  • when the actual argument to sub1 is of type type2, I get "The type of the actual argument differs from the type of the dummy argument."
  • when the actual argument to sub1 is of type type1, I get "If a dummy argument is allocatable or a pointer, the associated actual argument shall be polymorphic if and only if the dummy argument is polymorphic"

How can I achieve my goal of having sub1 work with an actual argument of type type1 or any type with extends type1 ?

Thanks!

[fortran]module mod_types
	type :: type1
		real :: coo(3)
	end type

	type, extends(type1) :: type2
		logical :: boo
	end type

	contains

	subroutine sub1(arg)
		implicit none
		! arguments
		class(type1),	allocatable, intent(in) :: arg(:)
		! private variables
		integer :: i
		! start work
		do i=1,size(arg)
			print '(3f6.2)', arg(i)%coo
		enddo
	end subroutine sub1
end module mod_types

program hello
	use mod_types
	implicit none

	!type(type1), allocatable :: my_var(:)	! with this line i get: If a dummy argument is allocatable or a pointer, the associated actual argument shall be polymorphic if and only if the dummy argument is polymorphic
	type(type2), allocatable :: my_var(:)	! with this line i get: The type of the actual argument differs from the type of the dummy argument.
	integer :: i

	allocate(my_var(10))
	do i=1,10
		my_var(i)%coo = [0.0,0.0,0.0]
	enddo

	call sub1(my_var)

end program hello[/fortran]


0 Kudos
1 Solution
Steven_L_Intel1
Employee
972 Views
Declare my_var as class(type1) and allocate it as:

allocate (type1::my_var(10))

or

allocate (type2::myvar(10))

View solution in original post

0 Kudos
4 Replies
Steven_L_Intel1
Employee
973 Views
Declare my_var as class(type1) and allocate it as:

allocate (type1::my_var(10))

or

allocate (type2::myvar(10))
0 Kudos
John4
Valued Contributor I
972 Views

Is that a workaround for a bug in the implementation, or the expected way? I ask, because it seems redundant to have to declare the variable as a class even when you only need it to work with one type.

0 Kudos
Steven_L_Intel1
Employee
972 Views
This is a restriction in the standard. The wording is pretty much as in the first error message. The F2003 standard says, in section 12.4.1.2:

"If a dummy argument is allocatable or a pointer, the associated actual argument shall be polymorphic if and only if the dummy argument is polymorphic, and the declared type of the actual argument shall be the same as the declared type of the dummy argument."

In your program, dummy argument arg of routine sub1 is both allocatable and polymorphic. Therefore, the standard requires that the actual argument be polymorphic, and that the declared type of the actual match the declared type of the dummy (type1). So this requires class(type1) for the actual argument. The reason for this is that an allocatable polymorphic requires extra information because the type can change with a reallocation.

Now... why do you declare arg as allocatable in sub1? In the example you provided, you don't change its allocation status. If you remove ALLOCATABLE, then the program compiles successfully with either type(type1) or type(type2). It's perfectly fine to pass an allocatable variable to a non-allocatable dummy argument if all you want is to reference the data.
0 Kudos
Alexis_R_
New Contributor I
972 Views
Thanks for your answers, Steve. In this test case, it was unnecessary to make dummy arg allocatable in sub, but I was exploring cases in my actual program where it might have made sense to keep the "allocatable" there.
0 Kudos
Reply