- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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,
How can I achieve my goal of having sub1 work with an actual argument of type type1 or any type with extends type1 ?
Thanks!
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]
1 Solution
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Declare my_var as class(type1) and allocate it as:
allocate (type1::my_var(10))
or
allocate (type2::myvar(10))
allocate (type1::my_var(10))
or
allocate (type2::myvar(10))
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Declare my_var as class(type1) and allocate it as:
allocate (type1::my_var(10))
or
allocate (type2::myvar(10))
allocate (type1::my_var(10))
or
allocate (type2::myvar(10))
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
"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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page