Fortran能否自动推断传入子程序的数组形状?
问题原因
你遇到的错误核心是显式接口缺失:Fortran 中如果子程序使用假定形状数组(dimension(:,:))作为形参,调用侧必须能访问到该子程序的显式接口,否则编译器只会传递数组首地址,不会传递数组维度、上下界等元信息,子程序就无法正确识别数组形状,输出的shape结果自然是错的。
报错说明
- 你用到的
dimension(*,*)是 Fortran 2003 引入的隐含形状数组语法,仅允许用于PARAMETER常量,不能作为普通子程序的形参,因此编译直接报错。如果要使用老式的假定大小数组,应该写为dimension(m,*),但需要额外传入数组维度参数m,且这种写法本身也无法通过shape()查询到完整的数组形状。
解决方法
推荐以下两种常用方案,均能让主程序获取到子程序的显式接口:
方案1:将子程序封装到Module中(最推荐)
新增模块文件array_utils.f90,内容如下:
module array_utils implicit none contains subroutine writeToArray( data ) real, dimension(:,:), intent(in) :: data write (*,*) "DEBUG writeToArray : shape(data) ", shape(data) end subroutine writeToArray end module array_utils
修改主程序program.f90,开头引入模块:
program test_arrayPass use array_utils implicit none ! === variables integer :: n real, dimension (:,:),allocatable :: data ! === Body n = 3 allocate(data(n,n)) write (*,*) "DEBUG test_arrayPass : shape(data) ", shape(data) call writeToArray( data ) end
原有的writeToArray.f90可以删除,这种写法适合项目中多个文件共用子程序的场景。
方案2:将子程序放入主程序的contains块中
适合小项目、单文件场景,修改program.f90如下:
program test_arrayPass implicit none ! === variables integer :: n real, dimension (:,:),allocatable :: data ! === Body n = 3 allocate(data(n,n)) write (*,*) "DEBUG test_arrayPass : shape(data) ", shape(data) call writeToArray( data ) contains subroutine writeToArray( data ) real, dimension(:,:), intent(in) :: data write (*,*) "DEBUG writeToArray : shape(data) ", shape(data) end subroutine writeToArray end
两种方案修改后直接用原Makefile编译运行,就能拿到正确的输出:
DEBUG test_arrayPass : shape(data) 3 3 DEBUG writeToArray : shape(data) 3 3
内容的提问来源于stack exchange,提问作者Prokop Hapala
相关产品推荐
相关产品推荐

