为什么带有假设形状参数的子程序不能有内部函数?
Why can't a subroutine with assumed-shape argument have an internal function?
我有一个带有假定形状数组的子程序,该数组还包含一个内部函数:
subroutine test(x)
real x(:)
contains
function a()
end
end
当我尝试用 f2py (f2py -c test.f90 -m test
) 编译它时,打印了以下错误:
gfortran:f77: /tmp/tmphb_l9bkr/src.linux-x86_64-3.7/test-f2pywrappers.f
/tmp/tmphb_l9bkr/src.linux-x86_64-3.7/test-f2pywrappers.f:11:10:
function a() ! in :test:test.f90:test
1
Error: Unclassifiable statement at (1)
/tmp/tmphb_l9bkr/src.linux-x86_64-3.7/test-f2pywrappers.f:13:13:
end function a
1
Error: Expecting END SUBROUTINE statement at (1)
但是,如果我删除内部函数 a()
,或者为数组指定一个明确的形状(例如 real x(5)
),它可以正常编译。我上面给出的代码有什么问题?
情况似乎很奇怪。为了更加确定,受 end function a
错误消息的启发,我添加了完整的结束语句
subroutine test(x)
real x
contains
function a()
end function a
end subroutine test
如您在错误消息中所见,gfortran 错误并非来自您的原始源代码,而是来自 /tmp/
目录中的不同源代码。如果你打开它,它看起来像这样:
C -*- fortran -*-
C This file is autogenerated with f2py (version:2)
C It contains Fortran 77 wrappers to fortran functions.
subroutine f2pywraptest (x, f2py_x_d0)
integer f2py_x_d0
real x(f2py_x_d0)
interface
subroutine test(x)
real, dimension(:) :: x
function a() ! in :nestedf:nestedf.f90:test
end function a
end subroutine test
end interface
call test(x)
end
它是一个用于调用您的子例程的包装器。这样做的原因是让 Python 更容易调用您的代码,而不需要 Python 理解假定的形状参数。但是f2py在创建接口的时候没有正确理解内部函数
不幸的是,你必须做出选择。您可以使用假定的形状参数,也可以使用内部函数。但是 f2py 不理解两者。或者您将不得不以某种方式拦截 f2py 临时文件并在继续之前修复它,但我不知道该怎么做。
包装器源代码中提到的 Fortran 77 不会让我分心。它们可能意味着可以在没有显式接口的情况下调用包装器本身,并且源文件是固定格式的。但它显然包含 Fortran 90 功能。
我有一个带有假定形状数组的子程序,该数组还包含一个内部函数:
subroutine test(x)
real x(:)
contains
function a()
end
end
当我尝试用 f2py (f2py -c test.f90 -m test
) 编译它时,打印了以下错误:
gfortran:f77: /tmp/tmphb_l9bkr/src.linux-x86_64-3.7/test-f2pywrappers.f
/tmp/tmphb_l9bkr/src.linux-x86_64-3.7/test-f2pywrappers.f:11:10:
function a() ! in :test:test.f90:test
1
Error: Unclassifiable statement at (1)
/tmp/tmphb_l9bkr/src.linux-x86_64-3.7/test-f2pywrappers.f:13:13:
end function a
1
Error: Expecting END SUBROUTINE statement at (1)
但是,如果我删除内部函数 a()
,或者为数组指定一个明确的形状(例如 real x(5)
),它可以正常编译。我上面给出的代码有什么问题?
情况似乎很奇怪。为了更加确定,受 end function a
错误消息的启发,我添加了完整的结束语句
subroutine test(x)
real x
contains
function a()
end function a
end subroutine test
如您在错误消息中所见,gfortran 错误并非来自您的原始源代码,而是来自 /tmp/
目录中的不同源代码。如果你打开它,它看起来像这样:
C -*- fortran -*-
C This file is autogenerated with f2py (version:2)
C It contains Fortran 77 wrappers to fortran functions.
subroutine f2pywraptest (x, f2py_x_d0)
integer f2py_x_d0
real x(f2py_x_d0)
interface
subroutine test(x)
real, dimension(:) :: x
function a() ! in :nestedf:nestedf.f90:test
end function a
end subroutine test
end interface
call test(x)
end
它是一个用于调用您的子例程的包装器。这样做的原因是让 Python 更容易调用您的代码,而不需要 Python 理解假定的形状参数。但是f2py在创建接口的时候没有正确理解内部函数
不幸的是,你必须做出选择。您可以使用假定的形状参数,也可以使用内部函数。但是 f2py 不理解两者。或者您将不得不以某种方式拦截 f2py 临时文件并在继续之前修复它,但我不知道该怎么做。
包装器源代码中提到的 Fortran 77 不会让我分心。它们可能意味着可以在没有显式接口的情况下调用包装器本身,并且源文件是固定格式的。但它显然包含 Fortran 90 功能。