Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29300 Discussions

Internal Procedures as actual arguements

adrianholt
Beginner
642 Views
The FORTRAN standard will not allow internal procedures to be actual arguements to another procedure. COMPAQ FORTRAN seems to allow this, which is a very nice feature. However the contained internal procedure I am using is an ARRAY FUNCTION which causes a compile error in COMPAQ. Is there any way around this so I can still use a CONTAINED ARRAY FUNCTION?

Example Below::

module obsvTest3

implicit none
private

integer, parameter :: iDim = 2
contains
!------------------------------------
subroutine test1 ()

! double precision, external :: testfun
! double precision, dimension(iDim), external :: testfun
! external :: testfun

call testmethod (testfun)

contains
!------------------------------------
function testfun ()

! double precision :: testfun
double precision, dimension(iDim) :: testfun

testfun = 1d0

end function testfun


end subroutine test1
!------------------------------------
subroutine testmethod (dFun)

double precision, dimension(iDim), external :: dFun
! double precision, external :: dFun
! external :: dFun

double precision, dimension (iDim) :: dLocal
! double precision :: dLocal

dLocal = dFun()

end subroutine testmethod

!-------------------------------------
end module obsvTest3
0 Kudos
2 Replies
james1
Beginner
642 Views
First, you want to pass a pointer to the routine as in CALL TESTMETHOD(LOC(TESTFUN)). Then in TESTFUN define an interface for the function it is to call, and assign the function pointer as in:
subroutine testmethod (lpFun)

interface
function testfun ()
  integer, parameter :: iDim = 2
  double precision, dimension(iDim) :: testfun
  end function
end interface
double precision, dimension (iDim) :: dLocal

integer (int_ptr_kind()) lpFun
pointer (dFunPtr, testfun)

dFunPtr = lpFun
dLocal = testfun()

James
0 Kudos
Steven_L_Intel1
Employee
642 Views
Your main problem is that you cannot declare an array-returning function using EXTERNAL. You must use an INTERFACE for this. If you do that, you run into an annoying aspect of the language which makes host-associated definitions invisible inside INTERFACE blocks. So you have to do it this way instead:

module mydefs
integer, parameter :: iDim = 2
end module mydefs

module obsvTest3
use mydefs
implicit none
private

contains
!------------------------------------
subroutine test1 ()

! double precision, external :: testfun
! double precision, dimension(iDim), external :: testfun
! external :: testfun 

call testmethod (testfun)

contains
!------------------------------------
function testfun ()

! double precision :: testfun
double precision, dimension(iDim) :: testfun

testfun = 1d0

end function testfun


end subroutine test1
!------------------------------------
subroutine testmethod (dFun)

interface
  function dFun
  use mydefs
  double precision, dimension(iDim) :: dFun
  end function dFun
  end interface

double precision, dimension (iDim) :: dLocal
! double precision :: dLocal

dLocal = dFun()

end subroutine testmethod

!-------------------------------------
end module obsvTest3


Steve
0 Kudos
Reply