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

Transfer real(kind=someKind) to a function

oleglebedev
New Contributor I
549 Views
Good day,
I`m trying to code some function which compares two number.
A simple code of this one is:
[fortran]  pure logical function compare(a,b,someKind) RESULT(res)
      implicit none
      integer, intent(IN) :: someKind
      real(kind=someKind), intent(IN) :: a,b
  res = abs(a)==abs(b)
  return
  end function compare
[/fortran]
This function is contained in a module (call it "FirstModule") and has some interface. I would like to call this function from another module (call it "MainModule"). The MainModule has a global constant as
dbl = seleceted_real_kind(p=20). The FirstModule don`t know anything about this dbl-global constant and it does`t have to. The dbl-parameter defines my real type variables. And I want to compare two real numbers calling
[fortran]module MainModule
USE global_module, only: dbl
USE FirstModule, only: compare
implicit none
!!! ...
subroutine show()
    real(kind=dbl) :: firstNumber, secondNumber
    logical :: res
res = compare( a=firstNumber, b=secondNumber, someKind=dbl )
write(*,*) "It is ", res
end subroutine show

!!! ...

end module MainModule
[/fortran]
When I compile the FirstModule separately I get an error message:
error #6683: A kind type parameter must be a compile-time constant. [SOMEKIND]

How can I specify the someKind intent(IN) variable in my function to compile my module separately?
0 Kudos
4 Replies
mecej4
Honored Contributor III
549 Views
You can write several comparison functions, each operating on two arguments, but differing as to the types of the arguments, put these into a module and overload these functions by a module procedure. For example:

[fortran]module compare_mod
   interface compare
      !module procedure cmpRR, cmpRD, cmpDR, cmpDD
	     pure function cmpRR(x, y) result (L)
		    real :: x, y
			logical :: L
	     end function cmpRD
	     pure function cmpRD(x, y) result (L)
		    real :: x
			double precision :: y
			logical :: L
	     end function cmpRD
		 ...{similar declarations for cmpDR and cmpDD}
   end interface
end module compare_mod
[/fortran]
and invoke the generic name compare with any of the combinations of argument types covered by the declarations above.

Of course, you have to provide implementations of the specific functions cmpRR, cmpRD, cmpDR and cmpDD.
0 Kudos
oleglebedev
New Contributor I
549 Views
I get theerror #6645: The name of the module procedure conflicts with a name in the encompassing scoping unit. [CMPRR]

But only with amoduleprocedure it is compiled.
0 Kudos
mecej4
Honored Contributor III
549 Views
Somehow my response #1 has disappeared, so here is a second attempt, with runnable code.

[fortran]module compare_mod
   interface compare
      module procedure cmpRR,cmpRD,cmpDR,cmpDD
   end interface
contains
   pure function cmpRR(x, y) result (L)
       real, intent(in) :: x, y
       logical :: L
       L = x == y
   end function cmpRR
   pure function cmpRD(x, y) result (L)
       real, intent(in) :: x
       double precision, intent(in) :: y
       logical :: L
       L = x == REAL(y)
   end function cmpRD
   pure function cmpDR(x, y) result (L)
       double precision, intent(in) :: x
        real, intent(in) :: y
       logical :: L
       L = REAL(x) == y
   end function cmpDR
   pure function cmpDD(x, y) result (L)
       double precision, intent(in) :: x, y
        logical :: L
        L = x == y
   end function cmpDD
end module compare_mod

program tst use compare_mod write(*,*)compare(1.0,2.0),compare(1d0,1.0),compare(2.0,2d0),compare(3d0,3d0) end program tst [/fortran]
0 Kudos
oleglebedev
New Contributor I
549 Views
mecej4, thank for your answer.
But I wrote in the first post:
The FirstModule don`t know anything about this dbl-global constant and it does`t have to.

I mean that a function comp_RKRK with intent(IN) a and b as areal(kind=someArbitraryKind) have somearbitrary kind which is transfered to one. And this module with this comp_RKRK, comp_II etc is compiled separetely from main project. And this module doesn`t know anything about a main project global var and it doesn`t have to.

[fortran]ELEMENTAL logical function comp_RKRK(a, b, someArbitraryKind) RESULT(res)
    implicit none
    integer, intent(IN) :: someArbitraryKind
    real(kind=someArbitraryKind), intent(IN) :: a, b
res = a==b
return
end function comp_RKRK[/fortran]
And of course, I reload its using INTERFACE block
[fortran]INTERFACE compare
  MODULE PROCEDURE comp_RKRK, comp_II ! etc
END INTERFACE[/fortran]
0 Kudos
Reply