[Bug libfortran/124668] STOP statement should probably flush OUTPUT_UNIT before issuing its message on ERROR_UNIT

kargl at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sun Mar 29 23:28:27 GMT 2026


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124668

--- Comment #9 from Steve Kargl <kargl at gcc dot gnu.org> ---
(In reply to Jerry DeLisle from comment #8)
> (In reply to Steve Kargl from comment #7)
> > (In reply to Walter Spector from comment #6)
> > 
> > > One can work around the problem by placing a FLUSH (OUTPUT_UNIT) statement
> > > just prior to the STOP.  But this seems silly.
> 
> It seems we do not have a concensus about whether this is a problem or not.
> 
> > 
> > Seems like good defensive programming as stdout and stdin
> > are the same "external file" (i.e., device).
> > 
> > And as already mentions, there are two environmental 
> > variables available to control buffering.
> 
> I did compare to flang and intel compilers and their behaviour agrees with
> Walter. The following trivial patch seems to do it. I also regression tested
> it and all is good. I would prefer to wait for after the 16 release if we do
> this.

Short version:

  The patch technically may break backwards compatibility with all
  previous versions of gfortran.

Long version:

All references are to F2023 draft (24-007, 2023-12-18)

  11.4 STOP and ERROR STOP statements

  Execution of a STOP statement initiates normal termination
  of execution.

  5.3.7 Termination of execution

  Termination of execution of a program is either normal termination 
  or error termination.  Normal termination occurs only when all images
  initiate normal termination and occurs in three steps: initiation,
  synchronization, and completion.

This is defines what is normal termination.  So, now, what does
'completion' mean?  (I'll note that the first appearance of 'completion'
is in 5.3.7.)

  12.5.7 CLOSE statement

  12.5.7.1 General
  ...
  During the completion step (5.3.7) of normal termination, all units
  that are connected are closed.  Each unit is closed with status KEEP
  unless the file status prior to termination of execution was SCRATCH,
  in which case the unit is closed with status DELETE.

That's it.  There is no requirement with regards to an order in
which the units are closed, and there is no guarantee that any
one unit will be completely written at the OS-level prior to any
other unit.

  12.3 External files

  12.3.1 External file concepts

  An external file is any file that exists in a medium external
  to the program.

  At any given time, there is a processor-dependent set of allowed
  access methods, a processor-dependent set of allowed forms, a
  processor-dependent set of allowed actions, and a processor-dependent
  set of allowed record lengths for a file.

  ...

  NOTE 3

  For more explanatory information on external files, see C.8.1.

  C.8.1.4 File connection (12.5)

  Before any input/output can be performed on a file, it needs to
  be connected to a unit.  The unit then serves as a designator for
  that file as long as it is connected.  To be connected does not
  imply that "buffers" have or have not been allocated, that
  "file-control tables" have or have not been filled, or that any
  other method of implementation has been used. Connection means
  that (barring some other fault) a READ or WRITE statement can be
  executed on the unit, hence on the file.

So, gfortran chose 2+ decades ago to use buffered IO for stdout (aka
OUTPUT_UNIT) and unbuffered IO for stderr (aka ERROR_UNIT).  Let's 
see what a draft of C23 (N3096.pdf) says

  At program startup, three text streams are predefined and need not
  be opened explicitly -- standard input (for reading conventional
  input), standard output (for writing conventional output), and
  standard error (for writing diagnostic output).  As initially opened,
  the standard error stream is not fully buffered; the standard input
  and standard output streams are fully buffered if and only if the
  stream can be determined not to refer to an interactive device.

As gfortran's OUTPUT_UNIT is stdout and ERROR_unit is stderr, it
simply uses whatever the companion C processor does (with possible
intervention from an environmental variable).

Now, a programmer might try to be defensive with

  flush(output_unit)
  stop

But, we find this nugget

  12.9 FLUSH statement
  ...
  NOTE 1

  Because this document does not specify the mechanism of file storage,
  the exact meaning of the flush operation is not precisely defined.  It
  is expected that the flush operation will make all data written to a
  file available to other processes or devices, or make data recently
  added to a file by other processes or devices available to the  program
  via a subsequent read operation.  This is commonly called "flushing
  input/output buffers".

There is no guarantee that 'flush(output_unit)' will completely write
output at an OS-level before the completion step of the 'stop' causes
output to error_unit.

Finally, repeating myself again, gfortran has two environmental 
variables that a programmer can use to control the buffering of
stdout and stderr.  Buffered IO will issue a syscall to write to
a file/device when a buffer is full (or the unit is closes).  
Unbuffered IO will issue a syscall on ever write/print statement.


More information about the Gcc-bugs mailing list