[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