以下Fortran程序在调用print_test
时冻结。
program test_prg
implicit none
integer :: mpi_enabled, ierr
call MPI_Initialized(mpi_enabled, ierr)
print *, print_test()
contains
function print_test() result(res)
real :: res
res = 0
print *, 'HELLO'
end function
end program
对print_test
的调用甚至可以在对MPI_Initialized
的调用之前,并且只要对MPI_Initialized
和print *, print_test()
的调用存在于程序中的某个位置。如果用MPI_Init
替换MPI_Initialized
,也可以重现同样的问题,但如果我删除它,则不能重现。如果我删除print *, 'HELLO'
,则它有效。如果我在单独的一行调用print_test
,然后打印结果,那么它就工作了。当使用gfortran
9.3.0(至mpifort
(进行编译时,观察到了该问题。使用ifort
编译时,相同的程序可以正常工作。MPICH版本为3.3.2。
这是gfortran
错误吗?有人知道如何解决这个问题吗?
有人向我指出,这个问题与递归IO有关,这显然是标准不允许的。简而言之,如果函数打印到一个单元,则不能在与同一单元相关联的打印语句的IO列表中调用它。必须将函数的返回值分配给一个变量,然后打印该变量,或者打印到另一个单元。不幸的是,不遵守此规则会导致运行时冻结,没有任何解释,而不是编译时错误。已经提出并回答了完全相同的问题,例如:
函数调用在包含写入语句时停止/挂起,但仅在编译期间链接到某些库时
和
打印到Fortran模块中定义的函数的标准输出