3

The following MCVE compiles and works just fine for me on Linux with all the versions of GCC I tried.

program temp

  implicit none

  print *, hello_message()

contains

  function hello_message() result(res)
    character(len=80) :: res
    ! Comment the string below, and everything works fine.
    print *, "Debug..."
    res = "Hello!"
  end function hello_message

end program temp

But on OS X and Windows the exact same program just stalls. I've tried different versions of gfortran from Homebrew, GCC Wiki, HPC OS X on OS X as well as few versions from MinGW-w64 project on Windows, but no luck. The code appears pretty fine for me, so what's wrong?

Wildcat
  • 8,701
  • 6
  • 42
  • 63
  • @francescalus, what is "recursive I/O"? You can probably call the way I/O is done in the example *nested*, but I doubt it is recursive, whatever it means. – Wildcat Nov 19 '15 at 13:12
  • It is recursive (at least in terms of Fortran - whether it's what would be inferred by the computer science ideal may be different), in that `hello_message` is invoked in a data transfer statement, and in that function there is another data transfer statement. From the Fortran standard: "An input/output statement that is executed while another input/output statement is being executed is a recursive input/output statement." – francescalus Nov 19 '15 at 13:14
  • 1
    @francescalus, well, OK. But whatever it is called, I still don't understand why it doesn't work. From reading Section 9.12 of the 2008 Standard I see no problems with this code. – Wildcat Nov 19 '15 at 13:25
  • 1
    It is an exact duplicate. The program directly violates F2008:9.12.2 as explained in the answer in the link. A child data transfer statement exception only applies to defined input/output which you do not do (and which is not supported by gfortran anyway). – Vladimir F Героям слава Nov 19 '15 at 13:43
  • @VladimirF, a rhetorical question then: why it even compiles? :| – Wildcat Nov 19 '15 at 13:46
  • Because it is not a constraint. Compilers are not required to detect it. Many programs which crash do compile. – Vladimir F Героям слава Nov 19 '15 at 13:46
  • @VladimirF, but then why is not it a constraint? And how do you know that compilers are not required to detect it? – Wildcat Nov 19 '15 at 13:49
  • Because it would be too difficult to check it. It is very similar to the check of indirect recursion by a function which is not declared as `recursive` or to the array bounds checks. Constraints are usually a syntactical thing, they are about where you can put what kind of statement. Less about the actual execution of the statement. – Vladimir F Героям слава Nov 19 '15 at 13:53
  • 1
    To add to the comment by @VladimirF, when you read the standard essentially the only things a compiler _must_ be able to detect wrong with a program are those numbered rules beginning with a label "C". Constraints given in free-form text are constraints on the programmer not the compiler. I'll note, though, that nagfor's run-time does indeed detect and complain about this recursive I/O. – francescalus Nov 19 '15 at 13:56
  • And to allow your program to work properly, you could write your "debug" line to a different unit, such as `error_unit` (if that's different from `output_unit`/`*`). – francescalus Nov 19 '15 at 13:58
  • Finally, I think this is a much clearer question than the other - I wonder if we can get them merged? – francescalus Nov 19 '15 at 14:01
  • @Wildcat I actually met the same problem before on OSX, and I was wondering why it works on Linux but not on OSX. Also, similar "recursive I/O" codes work with no problem for C++ (with either printf or cout), so I also wonder why the standard prohibits(?) the recursive I/O. – roygvib Nov 19 '15 at 14:08
  • @francescalus This is the intention of duplicates. To point people searching for different wording of the same problem to the solution. They are not to be deleted or anything. – Vladimir F Героям слава Nov 19 '15 at 14:12
  • @VladimirF Agreed, I was merely thinking that answers here would be much more clear and general than to the other (essentially, having the duplicate pointing the other way - which doesn't work when the good answer is over there already). – francescalus Nov 19 '15 at 14:18

0 Answers0