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

Procedure pointers as an OPTIONAL function argument

Michael_D_11
Beginner
660 Views

I am developing a project where a function makes use of an optional procedure pointer. Since the procedure pointer is OPTIONAL, an explicit interface is required. In other situations where I needed an interface block I typically made use of the auto-generated interface obtained during compilation of the procedure of interest. In my current case, this doesn't work as the compiler gives an error when compiling the interface block (as a module). For example, given the main program foo:

program foo
   use tfunct
   use BAR__genmod
   implicit none

   abstract interface
      function test(a, b, c)
         real                :: test
         integer, intent(IN) :: a
         real, intent(IN)    :: b
         real, intent(IN)    :: c
      end function test
   end interface

   integer a
   real b, c, d
   procedure(test), pointer :: ofunc

   ofunc => aTest

   a = 2; b = 5.0; c = 7.0
   call bar(a,b,c,d,ofunc)
   print *,d

   call bar(a,b,c,d)
   print *,d

end program foo

The function bar is in a separated module with the auto-generated interface BAR__genmod:

!COMPILER-GENERATED INTERFACE MODULE: Tue Nov 14 11:36:38 2017
! This source file is for reference only and may not completely
! represent the generated interface used by the compiler.
MODULE BAR__genmod
   INTERFACE 
   SUBROUTINE BAR(A,B,C,X,OFUNC)
      INTEGER(KIND=4), INTENT(IN) :: A
      REAL(KIND=4), INTENT(IN) :: B
      REAL(KIND=4), INTENT(IN) :: C
      REAL(KIND=4), INTENT(OUT) :: X
      INTERFACE 
         FUNCTION OFUNC(A,B,C)
         INTEGER(KIND=4), INTENT(IN) :: A
         REAL(KIND=4), INTENT(IN) :: B
         REAL(KIND=4), INTENT(IN) :: C
         REAL(KIND=4) ,OPTIONAL :: OFUNC
         END FUNCTION OFUNC
      END INTERFACE 
   END SUBROUTINE BAR
   END INTERFACE 
END MODULE BAR__genmod

and the ofunc points to aTest in the module tfunct, and aTest has the same interface as shown in the two files above.

When compiled, I get the following: error #6413: This global name is invalid in this context.   [OFUNC]

I understand the error, but don't understand how the compiler generated an invalid interface nor what the proper interface would look like. I realize that as a fallback I could always access the function foo through a module and use association, but I rather not use that approach.

Any insight would be appreciated.

 

0 Kudos
1 Solution
JVanB
Valued Contributor II
660 Views

Actually, we need the specification part of subroutine bar to be able to write a proper interface. Assuming dummy argument OFUNC to procedure bar is actually a procedure pointer and not a procedure, the interface body should look something like this:

!COMPILER-GENERATED INTERFACE MODULE: Tue Nov 14 11:36:38 2017
! This source file is for reference only and may not completely
! represent the generated interface used by the compiler.
MODULE BAR__genmod
   INTERFACE 
   SUBROUTINE BAR(A,B,C,X,OFUNC)
      INTEGER(KIND=4), INTENT(IN) :: A
      REAL(KIND=4), INTENT(IN) :: B
      REAL(KIND=4), INTENT(IN) :: C
      REAL(KIND=4), INTENT(OUT) :: X
      ABSTRACT INTERFACE
         FUNCTION OFUNC_PROTOTYPE(A,B,C)
         INTEGER(KIND=4), INTENT(IN) :: A
         REAL(KIND=4), INTENT(IN) :: B
         REAL(KIND=4), INTENT(IN) :: C
         REAL(KIND=4) :: OFUNC_PROTOTYPE
         END FUNCTION OFUNC_PROTOTYPE
      END INTERFACE
      PROCEDURE(OFUNC_PROTOTYPE), OPTIONAL, POINTER :: OFUNC
   END SUBROUTINE BAR
   END INTERFACE 
END MODULE BAR__genmod

 

View solution in original post

0 Kudos
4 Replies
JVanB
Valued Contributor II
661 Views

Actually, we need the specification part of subroutine bar to be able to write a proper interface. Assuming dummy argument OFUNC to procedure bar is actually a procedure pointer and not a procedure, the interface body should look something like this:

!COMPILER-GENERATED INTERFACE MODULE: Tue Nov 14 11:36:38 2017
! This source file is for reference only and may not completely
! represent the generated interface used by the compiler.
MODULE BAR__genmod
   INTERFACE 
   SUBROUTINE BAR(A,B,C,X,OFUNC)
      INTEGER(KIND=4), INTENT(IN) :: A
      REAL(KIND=4), INTENT(IN) :: B
      REAL(KIND=4), INTENT(IN) :: C
      REAL(KIND=4), INTENT(OUT) :: X
      ABSTRACT INTERFACE
         FUNCTION OFUNC_PROTOTYPE(A,B,C)
         INTEGER(KIND=4), INTENT(IN) :: A
         REAL(KIND=4), INTENT(IN) :: B
         REAL(KIND=4), INTENT(IN) :: C
         REAL(KIND=4) :: OFUNC_PROTOTYPE
         END FUNCTION OFUNC_PROTOTYPE
      END INTERFACE
      PROCEDURE(OFUNC_PROTOTYPE), OPTIONAL, POINTER :: OFUNC
   END SUBROUTINE BAR
   END INTERFACE 
END MODULE BAR__genmod

 

0 Kudos
Michael_D_11
Beginner
660 Views
OFUNC is a procedure pointer and your suggestion works perfectly. Thanks much for the assistance - I doubt I would have ever stumbled on this way of writing the interface.
0 Kudos
JVanB
Valued Contributor II
660 Views

Cool. Another syntax that I think should work is:

!COMPILER-GENERATED INTERFACE MODULE: Tue Nov 14 11:36:38 2017
! This source file is for reference only and may not completely
! represent the generated interface used by the compiler.
MODULE BAR__genmod
   INTERFACE 
   SUBROUTINE BAR(A,B,C,X,OFUNC)
      INTEGER(KIND=4), INTENT(IN) :: A
      REAL(KIND=4), INTENT(IN) :: B
      REAL(KIND=4), INTENT(IN) :: C
      REAL(KIND=4), INTENT(OUT) :: X
      INTERFACE
         FUNCTION OFUNC(A,B,C)
         INTEGER(KIND=4), INTENT(IN) :: A
         REAL(KIND=4), INTENT(IN) :: B
         REAL(KIND=4), INTENT(IN) :: C
         REAL(KIND=4) :: OFUNC
         END FUNCTION OFUNC
      END INTERFACE
      OPTIONAL :: OFUNC
      POINTER :: OFUNC
   END SUBROUTINE BAR
   END INTERFACE 
END MODULE BAR__genmod

The above is accepted by gfortran but ifort 16.0.2 produces the following error message:

bar1.f90(20): error #6429: This name has already been used as a dummy function n
ame.   [OFUNC]
      POINTER :: OFUNC
-----------------^
compilation aborted for bar1.f90 (code 1)

Is this fixed in the latest version of ifort?

 

0 Kudos
andrew_4619
Honored Contributor II
660 Views

In answer to #4, No

Compiling with Intel(R) Visual Fortran Compiler 18.0.0.124 [IA-32]...
dbug_parms.f90
C:\Users\...\dbug_parms\dbug_parms.f90(37): error #6429: This name has already 
been used as a dummy function name.   [OFUNC]
compilation aborted for C:\Users\...\dbug_parms\dbug_parms.f90 (code 1)

 

0 Kudos
Reply