2

The following Fortran program freezes on call to 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

The call to print_test can even be before the call to MPI_Initialized and still freeze as long as the call to MPI_Initialized and print *, print_test() is present somewhere in the program. The same problem can also be reproduced if MPI_Initialized is replaced with MPI_Init, but not if I remove it. If I remove print *, 'HELLO', then it works. If I call print_test on a separate line and then print the result, then it works. The problem is observed when compiled with gfortran 9.3.0 (through mpifort). The same program works without issues when compiled with ifort. MPICH version is 3.3.2.

Is this a gfortran bug? Does anyone know how to fix this issue?

francescalus
  • 30,576
  • 16
  • 61
  • 96
QNA
  • 1,047
  • 2
  • 14
  • 26

1 Answers1

2

It was pointed out to me that the issue has to do with recursive IO, which is apparently not permitted by the standard. In short, if a function prints to a unit, it cannot be called in IO list of a print statement associated with the same unit. One has to assign the return value of the function to a variable and then print the variable, or print to another unit. It's rather unfortunate that failure to comply with this rule results in runtime freeze with no explanation, instead of a compile-time error. The exact same questions have already been asked and answered, see for example:

Function call stopping/hanging when containing a write-statement, but only when linking with certain libraries during compilation

and

Print to standard output from a function defined in an Fortran module

QNA
  • 1,047
  • 2
  • 14
  • 26
  • A compile time error would be difficult as the problem has only occurred because the function was invoked from within an I/O statement, and when the function is being compiled the compiler may not be able to determine that this is the case, and similarly when the line invoking the function is compiled the compiler may not be able to determine that the function contains an I/O statement. This situation is all but unavoidable in the case of external functions. – Ian Bush Sep 09 '20 at 17:56