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

generic type-bound procedure rule is too strict ???

butette
Beginner
980 Views
So I am trying to implement a generic type-bound procedure using the latest release of ifort 12.0 from
composerxe-2011.0.084, and I find that the rule for generic interface in tbp is too strict. According to the
Fortran 2003 Handbook by Adams, Hendrickson, etc... page 465

=========================
The rules for distinguishability of specific procedures are built on the definition of
distinguishability of dummy arguments. Two dummy arguments are distinguishable if
neither is a subroutine and they differ in at least one of the following ways:
1. Neither is type-compatible (5.2) with the other. In the simple nonpolymorphic case,
this just means that the two types are different.
2. They differ in the value of a kind type parameter.
3. They differ in rank.
===========================
However when I try to implement a generic tbp where one of the dummy argument differs in rank, I would get
the following error using ifort
test.F90(41): error #8383: The dummy arguments of an overriding and overridden binding that correspond by position must have the same characteristics, except for the type of the passed object dummy arguments. [FUNC1]
but I don't have that problem when building using IBM xlf2003 compiler. Am I reading the rule wrong ? Is the IBM compiler wrong, or is ifort wrong in this case ? I am attaching the small example that illustrate my problem.
[bash]module junk_mod
type, abstract, public :: junkabs
   contains
      procedure(func1), deferred :: func1
      procedure(func2), deferred :: func2
      generic :: sumval  => func1, func2
end type junkabs

abstract interface
   subroutine func1( this, x, sum )
      import :: junkabs
      class(junkabs) :: this
      real, intent(in)  :: x(:)
   end subroutine func1
   subroutine func2( this, x, sum )
      import :: junkabs
      class(junkabs) :: this
      real, intent(in)  :: x(:,:)
   end subroutine func2
end interface
end module junk_mod
!--------------------
module junkspecial_mod
use junk_mod
type, extends(junkabs), public :: junkspecial
   contains
      procedure :: func1 => func1s
      procedure :: func2 => func2s
end type junkspecial

contains
   subroutine func1s( this, x, sum )
      class(junkspecial) :: this
      real, intent(in)  :: x(:)
      n = size(x)
      sum = 0
      do i=1,n
         sum = sum + x(i)
      enddo
      print *, 'func1: sum = ', sum
   end subroutine func1s
   subroutine func2s( this, x, sum )
      class(junkspecial) :: this
      real, intent(in)  :: x(:,:)
      n1 = size(x,dim=1)
      n2 = size(x,dim=2)
      sum = 0
      do j=1,n2
      do i=1,n1
         sum = sum + x(i,j)
      enddo
      enddo
      print *, 'func2: sum = ', sum
   end subroutine func2s
end module junkspecial_mod

!------------------
program tgeneric1
use junkspecial_mod
type(junkspecial) :: junk1
real, allocatable :: x1(:), x2(:,:)

n1 = 3
n2 = 2
allocate(x1(n1),x2(n1,n2))

do i=1,n1
   x1(i)=i
enddo
do j=1,n2
do i=1,n1
   x2(i,j)=i+j
enddo
enddo

call junk1%sumval(x1,sum)
call junk1%sumval(x2,sum)

end program tgeneric1
[/bash]
Thank you.
B.
0 Kudos
5 Replies
Steven_L_Intel1
Employee
980 Views
Interesting. I found that if I added an explicit declaration of the dummy argument SUM as:

real:: sum

in func1s and func2s that the error went away. However, SUM is implicit real, so this should not strictly be required. Still, it is good practice to explicitly declare everything and doing so will avoid the error. I will report this to the developers. Issue ID is DPD200166649.
0 Kudos
butette
Beginner
980 Views
Hi Steve,

I actually always use implicit none in my real code development. I was just trying to illustrate my problem on this little code example here and forgot about it. I am not sure that solve anything though since now I would get undefnied reference to func1_ and func2_
in MAIN, like it did not understand that I had a generic interface defined. If I change the invocation call from
call junk1%sumval(x1,sum)
call junk1%sumval(x2,sum)
to
call junk1%func1(x1,sum)
call junk1%func2(x2,sum)
then it will works, but that defeats the purpose of generic interface.
Did you actually get my test code to build and run ? If so which compiler were you using ?
Thanks,
B.
0 Kudos
Steven_L_Intel1
Employee
980 Views
I was just testing compilation - you're right, I get undefined externals if I link it. I'll let the developers know about this too.
0 Kudos
butette
Beginner
980 Views
Thank you Steve.
0 Kudos
Steven_L_Intel1
Employee
980 Views
These issues will be fixed in a future version of the compiler.
0 Kudos
Reply