- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
i have some problems with calling some C-functions from Fortran, if they (through an proper interface) are
- referenced through an procedure pointer, or
- procedure arguments.
For details see the code below, or download the tar.gz file in the attachement.
I compiled and debugged it with the latest Intel Fortran Compiler 11.1.072 32-Bit (the problem also occurs with version .069) on an Intel Core 2 Duo Laptop. IDB tells me, that the argument x is not proper transfered to the C function (same for rfun and ifun).
I'm not completely sure, if this code is perfectly conform with the F2003-std and if it is 100% interoperable to C, but the direct call of the C-functions (z=rfun(z) or z=ifun(z)) works, but decide self.
Many thanks and Best regards
Hans
i have some problems with calling some C-functions from Fortran, if they (through an proper interface) are
- referenced through an procedure pointer, or
- procedure arguments.
For details see the code below, or download the tar.gz file in the attachement.
I compiled and debugged it with the latest Intel Fortran Compiler 11.1.072 32-Bit (the problem also occurs with version .069) on an Intel Core 2 Duo Laptop. IDB tells me, that the argument x is not proper transfered to the C function (same for rfun and ifun).
I'm not completely sure, if this code is perfectly conform with the F2003-std and if it is 100% interoperable to C, but the direct call of the C-functions (z=rfun(z) or z=ifun(z)) works, but decide self.
[cpp]#-- ctest.h --#
typedef struct interval { double INF, SUP;} interval ;
#define _PROTOTYPE(function,params) function params
_PROTOTYPE(double rfun, (double x));
_PROTOTYPE(interval ifun, (interval x));
### ctest.h ###[/cpp]
[cpp]#-- ctestr.c --#
#include "ctest.h"
double rfun(double x){
double res;
res = x*x;
return(res);
}
### ctestr.c ###[/cpp]
[bash]#-- ctesti.c --#
#include "ctest.h"
interval ifun(interval x){
interval res;
res.INF=x.INF*x.INF;
res.SUP=x.SUP*x.SUP;
return(res);
}
### ctesti.c ###[/bash]
[fortran]#-- ftest.f90 --#
module consts
use, intrinsic :: iso_c_binding
implicit none
public
integer, parameter :: dp = c_double !kind(0.0d0)
type, bind(C) :: interval
real(dp) :: inf, sup
end type
end module consts
module clib
use consts
implicit none
public
abstract interface
function rmap(x) result(res) bind(C)
use consts, only : dp
implicit none
real(dp) :: res
real(dp), value, intent(in) :: x
end function rmap
end interface
abstract interface
function imap(x) result(res) bind(C)
use consts, only : interval
implicit none
type(interval) :: res
type(interval), value, intent(in) :: x
end function imap
end interface
interface fun
function rfun(x) result(res) bind(C)
use consts, only : dp
implicit none
real(dp) :: res
real(dp), value, intent(in) :: x
end function rfun
function ifun(x) result(res) bind(C)
use consts, only : interval
implicit none
type(interval) :: res
type(interval), value, intent(in) :: x
end function ifun
end interface
end module clib
program cuftest
use consts
use clib
implicit none
call rtest()
call itest()
call rproctest(rfun)
call iproctest(ifun)
contains
subroutine rtest()
real(dp) :: x, y
integer :: i
write(*,*) 'rtest'
x = 1.0_dp
y = 0.0_dp
do i=1,5
x = fun(x)
y = fun(y)
write(*,*) i, 'x=', x
write(*,*) i, 'y=', y
end do
end subroutine rtest
subroutine itest()
type(interval) :: x, y
integer :: i
write(*,*) 'itest'
x = interval(0.0_dp, 1.0_dp)
y = interval(1.0_dp, 1.0_dp)
do i=1,5
x = fun(x)
y = fun(y)
write(*,*) i, 'x=', x
write(*,*) i, 'y=', y
end do
end subroutine itest
subroutine rproctest(f)
real(dp) :: x, y, z
integer :: i
procedure(rmap) :: f
procedure(rmap), pointer :: g
g => rfun
write(*,*) 'rproctest'
x = 2.0_dp
y = 2.0_dp
y = 2.0_dp
do i=1,5
x = f(x)
y = g(y)
z = rfun(z)
write(*,*) i, 'x=', x
write(*,*) i, 'y=', y
write(*,*) i, 'z=', z
end do
end subroutine rproctest
subroutine iproctest(f)
type(interval) :: x, y, z
integer :: i
procedure(imap) :: f
procedure(imap), pointer :: g
g => ifun
write(*,*) 'iproctest'
x = interval(1.0_dp, 2.0_dp)
y = interval(1.0_dp, 2.0_dp)
z = interval(1.0_dp, 2.0_dp)
do i=1,5
x = f(x)
y = g(y)
z = ifun(z)
write(*,*) i, 'x=', x
write(*,*) i, 'y=', y
write(*,*) i, 'z=', z
end do
end subroutine iproctest
end program cuftest
### ftest.f90 ###[/fortran]
Many thanks and Best regards
Hans
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think your source is ok. In proctest, the compiler is ignoring the VALUE attribute specified for the argument in abstract interface rmap. I'll report this to the developers - thanks. Issue ID is DPD200155475.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In case anyone is curious, I could show the same results on Windows, using gcc .o files linked into the ifort 11.1.065 ia32 compilation.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I reproduced this on Windows easily. I also constructed a Fortran-only sample. Procedure pointers are not required to see this - simply a PROCEDURE declaration that names an abstract interface with VALUE specified for an argument will do the trick. I also found that the compiler is ignoring BIND(C) specified in an abstract interface.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I expect this to be fixed in 12.0 Update 4.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page