fortran - C_FUNLOC 的结果是标量还是数组?
问题描述
我试图将一些 Fortran 子例程表示为c_funptr
( ) 以通过漂亮的fdict库void *
创建字典。在此处遵循 GCC 文档,我尝试调用. 然而 gfortran 似乎返回一个数组而不是一个标量值。c_funloc
c_funptr
这是编译器中的错误还是我遗漏了一些重要的东西?
输出gfortran -v
:
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/8.3.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release --enable-default-pie --enable-default-ssp --enable-cet=auto
Thread model: posix
gcc version 8.3.0 (GCC)
我也尝试过使用 ifort(版本 19.0.2.187),它提供了所需的行为(见下文)。
MWE:
! = minimum.f90 =
module test
use iso_c_binding
implicit none
interface test_funptr
module procedure test_funptr0
module procedure test_funptr1
end interface test_funptr
contains
subroutine test_funptr0(fp)
type(c_funptr) :: fp
write(*,*) "fp0!"
end subroutine test_funptr0
subroutine test_funptr1(fp)
type(c_funptr), dimension(:) :: fp
write(*,*) "fp1!", shape(fp)
end subroutine test_funptr1
function bar(x) result(y) bind(c)
real(c_double) :: x
real(c_double) :: y
y = -x**2 + x + 1
end function bar
end module test
program main
use iso_c_binding
use test
implicit none
call test_funptr(c_funloc(bar))
end program main
编译gfortran minimum.f90 -o min
各处的预期输出:
fp0
实际行为:fp1
对于 gfortran,fp0
对于 Intel 编译器,形状为零。
也许我只是错过了 gfortran 的正确选择?
解决方案
c_funloc
Fortran 标准将内部模块的函数iso_c_binding
指定为具有类型标量c_funptr
(Fortran 2018、18.2.3.5,在 Fortran 2003 和 Fortran 2008 中类似)作为函数结果。
当程序本身符合要求时,将函数结果作为数组违反了 Fortran 标准。
但是,在这种情况下,gfortran 不提供数组函数结果:您可以使用简单的方法来测试它,例如
print*, SHAPE(C_FUNLOC(bar))
相反,gfortran 未能将通用过程正确解析为test_funptr
特定的test_funptr0
.
也考虑这种情况
use, intrinsic :: iso_c_binding, only : c_funptr, c_null_funptr
use test, only : test_funptr, test_funptr1
type(c_funptr) :: ptr = C_NULL_FUNPTR
call test_funptr(ptr)
call test_funptr1(ptr)
end
gfortran 8 错误地解析了泛型并允许直接调用test_funptr1
.
推荐阅读
- python - 使用 plotly 创建带框架的地理地图
- python - 如何在帖子请求中使用特殊字符(重音)
- python - 如何在 pythonanywhere.com 中使用 Firefox webdriver
- visual-studio-code - 通过 Visual Studio Code 中的任务将文件夹添加到工作区
- python - Python单元测试模拟导入和检查断言调用
- html - scrollTop 在移动设备上不起作用
- ionic-framework - @ionic-native/core/decorators/interfaces.ts(104,22) 中的错误:错误 - 在“插件”的模板编译期间
- mysql - 为什么此 RIGHT 连接返回状态为未决状态的发票?
- algorithm - 计算网格中标记节点k距离内的节点
- react-native - React Native:更改权限请求和警报中使用的默认语言