print vs write Fortran statements
The Fortran 2003 standard constitutes a strong foundation of “modern Fortran”. Modern Fortran (Fortran ≥ 2003) is so different in capabilities and coding style from Fortran 77 as to be a distinct, highly backward compatible language. Almost all of Fortran 95 was incorporated into Fortran 2003, except for a few obscure little used and confusing features deprecated and already unsupported by some popular compilers.
Writing to console effectively: write(*,*)
grew out of non-standard use of Fortran 66’s write
statement that was introduced for device-independent sequential I/O.
Although write(*,*)
became part of Fortran 77 for printing to console standard output, the Fortran 77 print
command is more concise and more importantly visually distinct.
That is, where the full versatility of the write
command is not needed, print
should be used to help make those cases where write
is needed more distinct.
Assembly language comparison: print *,'hi'
and write(*,*) 'hi'
are IDENTICAL in assembly, within modern compilers as it should be.
In general, disassemble Fortran executables with:
gfortran myprog.f90
objdump --disassemble a.out > myprog.s
Fortran 2003 finally settled the five-decade old ambiguity over console I/O with the intrinsic iso_fortran_env
module, which is often invoked at the top of a Fortran module like:
module mymod
use, intrinsic:: iso_fortran_env, only: stdout=>output_unit, stdin=>input_unit, stderr=>error_unit
The =>
operators are here for renaming (they have other meanings for other Fortran statements).
It’s not necessary to rename, but it’s convenient for the popularly used names for these console facilities.
Recommendation: routine console printing:
print *,'my text'
For advanced console printing, whether to output errors, use non-advancing text, or toggle between log files and printing to console, use write(stdout,*)
or the like.
Example: print to stdout console if output filename not specified
use, intrinsic:: iso_fortran_env, only: stdout=>output_unit
implicit none (type, external)
character(:), allocatable :: fn
integer :: i, u, L
call get_command_argument(1, length=L, status=i)
if (i /= 0) error stop "first command argument not available"
allocate(character(L) :: fn)
call get_command_argument(1, fn)
if (i==0) then
print '(a)', 'writing to ' // fn
open(newunit=u, file=fn, form='formatted')
else
u = stdout
endif
i = 3 ! test data
write(u,*) i, i**2, i**3
if (u /= stdout) close(u) ! closing stdout can disable text console output, and writes to file `fort.6` in gfortran
print *,'goodbye'
! end program implies closing all file units, but here we close in case you'd use in subprogram (procedure), where the file reference would persist.
end program
Non-advancing stdout/stdin (for interactive Fortran prompts)