This program works well with ifort, ifx and AMD flang, but with gfortran in my system
gcc version 13.1.0 (Ubuntu 13.1.0-8ubuntu1~22.04)
it prints nothing at run-time and has to be stopped manually. Is the bug in my program or gfortran? The program:
program test
! f2008 using execute_command_line and assuming Linux
implicit none
print "(A,L2)", 'I am john',iam('john')
print "(A,L2)", 'I am JOHN',iam('JOHN')
contains
logical function iam( name)
character(*),intent(in)::name
integer estat
character(len(name)+38):: cmd
cmd = 'if [ `whoami` != "'//name//'" ]; then exit 1; fi'
call execute_command_line(cmd,exitstat=estat)
iam = (estat==0)
end function iam
end program test
then I think the code will work (it does on MacOS+gfortran). Of course, the code is not doing recursive i/o, so this appears to be some kind of compiler or library bug.
[edit] I experimented a little more with this. It appears that the error has nothing to do with the execute_command_line intrinsic. If you comment out that call, the program still hangs. I also experimented a little with constructing the cmd string with substring indexing and assignments,
cmd(1:18) = 'if [ `whoami` != "'
cmd(18+1:18+len(name)) = name
cmd(19+len(name):) = '" ]; then exit 1; fi'
and the program still hangs. If you eliminate cmd, and just insert the expression as the subroutine argument, it still hangs. I don’t see anything wrong with either the original code or any of these modified versions, they all look alright to my eye. One can disagree with the concept of executing functions just for side effects (i.e. a subroutine might be better), but the language allows this so it looks like it should work.
A minimalist version, hanging on the second call (in the print):
program test
implicit none
logical :: foo
! OK:
call execute_command_line("export A=3")
foo = iam()
! OK:
print "(L2)", foo
! NOK (with gfortran):
print "(L2)", iam()
contains
logical function iam()
call execute_command_line("export A=3")
end function iam
end program test
COMMAND shall be a default character scalar. It is an INTENT (IN) argument. Its value is the command line to be executed. The interpretation is processor dependent.
This is exactly where the issue lies. With gfortran you cannot call a function involving I/O from a print statement. This also hangs:
program test
implicit none
print "(A,L2)", 'I am john',iam('john')
contains
logical function iam( name)
character(*),intent(in)::name
print *, 'hello world!'
iam = .false.
end function iam
end program test
probably the bash script still involves accessing stdout
This is true when the iam() function has itself a print/write statement. But the original code had no print/write statements in the function.
While this is true in some cases, the code still hangs when the execute_command_line() operation does not write to stdout. Furthermore, on unix/posix operating systems, the execute_command_line() operation is performed in a separate process. One normally expects separate processes to have their own enviornments, their own file handles, etc., so one would expect this to work even if it does write to stdout (possibly with the results interlaced together in some arbitrary way).
This does work with other compilers, so it is not an OS feature, it appears to be specific to the gfortran compiler and/or its i/o libraries. And it fails on both linux and MacOS in a similar way, both unix/posix systems, but very different kernels.