问题描述
gfortran编译器具有interoperability option -fc-prototypes,可为可互操作的函数(具有BIND(C)属性)生成正确的C-prototype。
在链接中写道:“对于函数指针,将生成一个指向返回int且没有显式参数列表的函数的指针。”
我用一些包含BIND(C)子例程的代码进行了尝试,该子例程将函数指针指向带有2个整数参数的子例程。在文件test.F95
中获取Fortran代码:
subroutine test(pf) bind(c)
use,intrinsic :: iso_c_binding
implicit none
type(c_funptr),intent(in),value :: pf
abstract interface
subroutine fproto(x,y) bind(c)
use iso_c_binding,only: c_int
integer(c_int),value :: x,y
end subroutine fproto
end interface
procedure(fproto),pointer :: f
call c_f_procpointer(pf,f)
call f(1,2)
end subroutine test
编译为:gfortran test.F95 -c -Wall -fc-prototypes > proto.h
#include <stddef.h>
#ifdef __cplusplus
#include <complex>
#define __GFORTRAN_FLOAT_COMPLEX std::complex<float>
#define __GFORTRAN_DOUBLE_COMPLEX std::complex<double>
#define __GFORTRAN_LONG_DOUBLE_COMPLEX std::complex<long double>
extern "C" {
#else
#define __GFORTRAN_FLOAT_COMPLEX float _Complex
#define __GFORTRAN_DOUBLE_COMPLEX double _Complex
#define __GFORTRAN_LONG_DOUBLE_COMPLEX long double _Complex
#endif
void f ();
void fproto (int x,int y);
void test (int (*pf)());
#ifdef __cplusplus
}
#endif
如您所见,抽象接口中子例程fproto
的原型是正确的。但是test
子例程的参数(即函数指针)的正确C原型应为:
void (*pf)(int,int)
但是gfortran会生成
int (*pf)()
这根本不匹配。这有什么意义呢?这是否意味着我应该始终将函数指针传递给返回int的函数?还是这只是(故意地?)产生了错误?
解决方法
gfortran正在按设计和文档的方式工作(在第二段的问题中引用了相关的文档!)。
子例程测试将通用C函数指针作为参数。从该子例程的接口的互操作性的角度来看,可以传入任何函数。gfortran对任何函数的匹配函数的解释是“指向没有返回明确参数列表的int的函数的指针”。
Fortran过程指针与函数指针的关联是执行时间活动。该原型描述了函数的特性,这是一个编译时概念。