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

Procedure pointer compile error

andrew_4619
Honored Contributor III
366 Views

I made an example below redacted from some code that has worked OK for several years. It builds in IFORT and IFX with standards checking on. I tried gfortran 10.2.0 and 15.2.0 and get the error:


19 | call GetProcAddress_helper( DriverInstalled )
| 1
Error: Interface mismatch in dummy procedure 'procptr' at (1): 'driverinstalled' is not a subroutine

module testy
    use, intrinsic :: iso_c_binding, only: C_INT32_T, C_INT8_T
    implicit none(type, external)
    integer, parameter :: BYTE    = C_INT8_T
    integer, parameter :: bool    = C_INT32_T
    !
    abstract interface
      function mDriverInstalled(abyte) bind(C)
         import 
         !DIR$ ATTRIBUTES STDCALL :: mDriverInstalled
         !GCC$ ATTRIBUTES STDCALL :: mDriverInstalled
         integer(bool)        :: mDriverInstalled
         integer(byte), value :: abyte
      end function mDriverInstalled
    end interface
    procedure(mDriverInstalled), pointer :: DriverInstalled
contains
subroutine test()
    call GetProcAddress_helper( DriverInstalled )
end subroutine test
subroutine GetProcAddress_helper( procptr )
    procedure(), intent(inout), pointer :: procptr
    ! assign pointer to proc in dll using LoadLibrary, GetProcAddress C_F_PROCPOINTER 
end subroutine GetProcAddress_helper
end module testy

 

Is my code bad and if it is should IFX give an error?

 

0 Kudos
1 Solution
Steve_Lionel
Honored Contributor III
287 Views

I think your code is OK. Specifically, Fortran 2018 (and 2023, but let's go with the more common denominator) says, for a procedure declaration statement, "If proc-interface does not appear, the procedure declaration statement does not specify whether the declared procedure entities are subroutines or functions." (15.4.3.6p4) Therefore, gfortran is incorrect in complaining that you're passing a function pointer to that argument.

View solution in original post

0 Kudos
4 Replies
Steve_Lionel
Honored Contributor III
288 Views

I think your code is OK. Specifically, Fortran 2018 (and 2023, but let's go with the more common denominator) says, for a procedure declaration statement, "If proc-interface does not appear, the procedure declaration statement does not specify whether the declared procedure entities are subroutines or functions." (15.4.3.6p4) Therefore, gfortran is incorrect in complaining that you're passing a function pointer to that argument.

0 Kudos
thismarkjohnson
Beginner
227 Views

Your code is non-standard, and gfortran is correct to error.

The issue is here:

subroutine GetProcAddress_helper( procptr )

       procedure(), intent(inout), pointer :: procptr

An untyped procedure() dummy defaults to a subroutine, but you are passing a function pointer (DriverInstalled). That’s a procedure interface mismatch.

IFORT/IFX are being too permissive and should warn/error, but they don’t.

Correct fix: give the dummy the same abstract interface:

subroutine GetProcAddress_helper( procptr )

            procedure(mDriverInstalled), pointer, intent(inout) :: procptr

end subroutine

Or use a generic abstract interface that matches functions.

Bottom line:

Your code is invalid per the standard gfortran is right IFX should diagnose this, but currently doesn’t

0 Kudos
andrew_4619
Honored Contributor III
186 Views

Thanks for the feedback. Having a specific named interface would defeat the whole point of the real helper in the actual application, as it is used to set up a list of functions in a dll based on either ordinal or name.

I believe Steve's note above that Gfortran is wrong is correct, or more specifically I think it is an F2018 feature that is not implemented in Gfortran. I had the same problem with the "stat="  arg on move_alloc.  

In this case I have just rejigged to code so it works OK in both systems.

0 Kudos
Steve_Lionel
Honored Contributor III
164 Views

@thismarkjohnson wrote:

Your code is non-standard, and gfortran is correct to error.

 

An untyped procedure() dummy defaults to a subroutine, but you are passing a function pointer (DriverInstalled). That’s a procedure interface mismatch.


This is not correct, see my quote from the standard. This text also appears in Fortran 2008, so it isn't even new.

gfortran is not even fully compliant with Fortran 2003 and misses a lot of edge cases. 

0 Kudos
Reply