As of Fortran 2008, it is legal to pass an internal procedure as an actual argument. This is handy because the internal procedure can reference data in the body of the procedure or program in which it is contained. The following is a simple example showing how this mechanism can be used to pass “extra arguments” to a quadrature routine.
module integration
implicit none
abstract interface
function integrand(x)
real, intent(in) :: x
real :: integrand
end function integrand
end interface
contains
function trapz(f, a, b)
procedure(integrand) :: f
real, intent(in) :: a, b
real :: trapz
trapz = (b - a)/2 * ( f(a) + f(b) )
end function trapz
subroutine doit
integer :: n
do n = 0, 5
print *, n, trapz(f, 0., 1.)
end do
contains
function f(x) result(y)
real, intent(in) :: x
real :: y
y = x**n
end function f
end subroutine doit
end module integration
program check
use integration, only: doit
implicit none
call doit
end program check
The GCC wiki states that this has been implemented in gfortran since 2010 (Fortran2008Status - GCC Wiki). However, when I build and run the above, the program terminates unsuccessfully.
I am using gfortran 10.3.0 on Windows. Trusting the GCC wiki, I am led to think this is some Windows-specific issue. Can others Windows users check if the above code executes correctly? Can non-Windows users verify that it does indeed work on other platforms?
I tried your code on Windows with gfortran12.2.0 and fpm 0.8.1 and everything works. I put your program check within a check.f90 file in the test folder, and the module within its own file in the src folder.
I code in Windows with gcc and never had problems without explicit or abstract interfaces.
I can’t run your test now, but if you look for me in guthub, you will find "HR-WENO’ and "pbepack’ which make extensive use of that feature. Both compile perfectly with Windows + gcc.
I’m tempted to say the problem might be related with fpm, not the compiler (tried with gfortran 4.9 and it also works)… @nshaffer could you share your .toml file? which fpm version are you using?
Thanks all for the wide variety of tests; they are really helpful sanity checks. On both machines where I have this issue (both employer-managed), I am using an old version of @lkedward’s Windows quick-start, where gfortran comes from MinGW. I guess it is possible that the build is not configured quite right, or perhaps a Windows update broke things and I need to reinstall. Either way, this is looking like a problem with my specific combination of OS settings and/or GCC configuration.
@nshaffer , if it’s possible for you on this employer-managed devices to install Intel oneAPI HPC toolkit for Fortran, you can try out IFORT / IFX and the program response with it might help you figure out the issue.
As you will know, developers on Windows OS are prone to use DLLs (shared libraries) to encapsulate codes such as what you show in the Fortran MODULE you named as integration. And one way to manage control what can be accessed from such as user library (DLL) is via what Microsoft calls module-definition (DEF) files.
So you will notice in the console output below, with your MODULE code in a file named i.f and your caller program check in a file named p.f, Intel’s newer LLVM based processor IFX works as you would expect with the code you provide also when the MODULE code is contained in a shared lbrary:
C:\temp>type i.def
LIBRARY i
EXPORTS
INTEGRATION_mp_DOIT @1
C:\temp>ifx /c /standard-semantics /free i.f
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2023.1.0 Build 20230320
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
C:\temp>link i.obj /dll /def:i.def /out:i.dll
Microsoft (R) Incremental Linker Version 14.34.31937.0
Copyright (C) Microsoft Corporation. All rights reserved.
Creating library i.lib and object i.exp
C:\temp>ifx /c /standard-semantics /free p.f
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2023.1.0 Build 20230320
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
C:\temp>link p.obj i.lib /subsystem:console /out:p.exe
Microsoft (R) Incremental Linker Version 14.34.31937.0
Copyright (C) Microsoft Corporation. All rights reserved.
C:\temp>p.exe
0 1.000000
1 0.5000000
2 0.5000000
3 0.5000000
4 0.5000000
5 0.5000000
I am wondering what the error message (“Execution failed”) actually means (i.e., is this a build failure, or some runtime error?) It might be useful if more info can be obtained with some option (like -verbose?)
I just tested with the latest version of the quick-start Fortran environment (gcc/gfortran v12.2.0 & fpm 0.8.2) and I’m getting the same output as everyone else: