Elementary functions cannot point to procedure pointers

I am trying to use a procedure pointer (a new feature in Fortran 2003) to point to an elemental function, but it does not work. I really need an ELEMENTAL function and it needs a pointer. Is it impossible to point to an elemental function in Fortran?

  module elemfunc implicit none contains elemental function fun111(x) result(y) real*8, intent(in) :: x real*8 :: yy = x**2+1 end function fun111 end module elemfunc program testptr use elemfunc implicit none interface elemental function func (z) real*8 :: func real*8, intent (in) :: z end function func end interface procedure (func), pointer :: ptr ptr => fun111 print *, ptr( (/1.0d0,2.0d0/) ) end program testptr 

Error message:

 main.f90:12.7:ptr=>fun111 1 Nonintrinstic elemental procedure pointer 'func111' is invalid in procedure pointer assignment at (1) 
+6
source share
2 answers

Section 7.4.2 Pointer Assignment the fortran 2003 standard explicitly states that this is unacceptable:

 C728 (R742) The proc-target shall not be a nonintrinsic elemental procedure 

(This limitation still exists in the fortran 2008 standard, so it was not relaxed.)

+3
source

I had the same problem and I didn’t even understand that it was a problem until I compiled gfortran. Unfortunately, it is also forbidden to have bogus procedure arguments for elementary procedures. However, it is still possible to achieve the desired functionality, although it is a bit ragged.

What you can legally do is call an elementary function a pure function. Depending on your needs, an elemental function can be type-bound or not.

Option 1

Place the pointer and the procedure function inside the module:

 module A implicit none procedure(func_IF), pointer :: ptr => null() abstract interface pure function func_IF(x) real, intent(in) :: x real :: func_IF end function end interface contains ! Non type bound elemental elemental function myfun1(x) result(r) real, intent(in) :: x real :: r if(associated(ptr)) r = ptr(x) end function end module 

Second option

Place both pointers and functions inside the derived type:

 module B implicit none type :: foo procedure(func_IF), nopass, pointer :: ptr => null() contains procedure, pass :: myfun2 end type abstract interface pure function func_IF(x) real, intent(in) :: x real :: func_IF end function end interface contains ! Type bound elemental elemental function myfun2(this, x) result(r) class(foo), intent(in) :: this real, intent(in) :: x real :: r if(associated(this%ptr)) r = this%ptr(x) end function end module 

A small test program:

 program main use A use B implicit none type(foo) :: myfoo myfoo%ptr => bar ptr => bar print*, myfun1([10., 20.]) print*, myfoo%myfun2([10., 20.]) contains ! Demo pure function with interface func_IF pure function bar(x) real, intent(in) :: x real :: bar bar = x**2 end function end 
+2
source

All Articles