View Issue Details

IDProjectCategoryView StatusLast Update
0031113FPCDocumentationpublic2016-12-14 18:51
ReporterThaddy de KoningAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
PlatformallOSallOS Versionall
Product Version3.1.1Product Build35112 
Target Version3.2.0Fixed in Version3.1.1 
Summary0031113: IOResult documentation not clear enough
DescriptionIn {$I-} it should be noted that all IO operations are ignored until IOResult is read. This can be really confusing, so a little extra remark should be in place.
Steps To ReproduceConsider:
program File_assign;
 {$mode objfpc}{$H+}
uses
   CRT, sysutils;
 
var
   FileX: text;
   X: double;
 
begin
  try
{$I-}
    assign(FileX,'FileX1');
    close(FileX);
{$I+}
  // if IoResult <> 0 then writeln('Failed');
  finally
    begin
      writeln('End of program. ');
      readkey;
    end;
  end;
end.

In this case, because IO operations are ignored, it seems like the finally block is never executed since writeln and readkey are IO operations.
When you remove the comment, so IOResult is read, you will get the begavior as expected.
Additional InformationSee http://forum.lazarus.freepascal.org/index.php/topic,35115.msg231678.html#msg231678
TagsNo tags attached.
Fixed in Revision1375
FPCOldBugId
FPCTarget
Attached Files

Activities

Thaddy de Koning

2016-12-13 12:22

reporter   ~0096737

I mean of course in case an IO error occurs, subsequent IO operations are ignored until the error is reset. By reading IOResult. It can actually crash the program at runtime.

Jonas Maebe

2016-12-13 12:52

manager   ~0096738

readkey is not a standard IO operation and is unrelated to inoutres/ioresult. It will/should always be executed.

Thaddy de Koning

2016-12-13 13:07

reporter   ~0096739

Last edited: 2016-12-13 13:11

View 2 revisions

Writeln is... It needs clarification. Just curious, How come readkey is not an Input operation?

Jonas Maebe

2016-12-13 13:13

manager   ~0096740

readkey comes from the crt unit. Routines from the crt unit are not standard IO routines.

Thaddy de Koning

2016-12-13 13:52

reporter   ~0096741

Ah, I see. Some routines are more equal than others ;)
Anyway, it needs some clarification.

Jonas Maebe

2016-12-13 14:04

manager   ~0096742

The system unit is standard/part of the language. The rest is not. TFileStream doesn't care about IOResult either.

Sergei Gorelkin

2016-12-13 17:51

developer   ~0096746

This isn't a documentation issue. It is a critical flaw in RTL implementation. A single I/O error in {$i-} state entirely disables all subsequent file operations of current thread until reset by calling IoResult.

Such design is good for {i+} state, when compiler automatically inserts IoResult checking code after every file operation. However in {$i-} state there is no way to ensure that programmer does the same.

It is also Delphi incompatible: Delphi does not ignore file operations between one that ends up with error and subsequent call to IoResult.

Max Nazhalov

2016-12-13 18:44

reporter   ~0096747

Last edited: 2016-12-13 18:47

View 2 revisions

This is BP7 behavior -- it ignores text (and only text) file reads and writes until InOutRes=0 (see TGPC.ASM "Textfile Low-level I/O" from public RTL sources).

Sergei Gorelkin

2016-12-13 22:07

developer   ~0096751

FPC ignores both text and block i/o operations.

Maybe this behavior had its reasons in DOS/BP7 times, but I believe it's really time to move away from it.

Jonas Maebe

2016-12-13 22:14

manager   ~0096752

I don't think the reason is tied to a particular time. It would probably have made more sense if it was tied to an individual (text)file, but I think the reasoning is "if an I/O error happened before and you didn't handle it, then blindly performing more I/O (to the same file) is likely to mess up things even further".

Sergei Gorelkin

2016-12-13 23:47

developer   ~0096757

I agree that ignoring operations on particular text file is at least somewhat reasonable (although *checking* IoResult is not the same as actual *handling* errors). But doing it globally is just insane.

Jonas Maebe

2016-12-13 23:54

manager   ~0096758

Well, it is a global error checking mechanism...

Thaddy de Koning

2016-12-14 07:58

reporter   ~0096763

Last edited: 2016-12-14 08:00

View 2 revisions

Sergei, "Delphi does not ignore file operations between one that ends up with error and subsequent call to IoResult" is not true as my tests show.
Delphi's behavior is exactly the same as in FPC.

The current behavior is fully Delphi compatible.
But the Delphi documentation explains the effect a bit better.
Sergei seems under the impression that Delphi does a better job here, but Delphi docs say:
"If an I/O error occurs and I/O-checking is off, all subsequent I/O operations are ignored until the internal error flag is cleared. Calling IOResult clears the internal error flag."

This information/explanation is missing from the fpc IOResult documentation.


That is really all that my bugreport is about.

Sergei Gorelkin

2016-12-14 11:02

developer   ~0096765

Well, maybe the behavior has changed in recent Delphi versions, but with Delphi 7 the program under "Steps to reproduce" (after removing the CRT from uses clause and replacing 'readkey' with 'readln') prints "End of program", then shows Windows error reporting dialog and prints an exception information.
The same program compiled with trunk FPC does not print "End of program".

If I comment out the line with {$I+}, then Delphi 7 compiled program prints "End of program" and waits for Enter key, and FPC-compiled one exits without any message and without waiting.

Max Nazhalov

2016-12-14 12:31

reporter   ~0096767

Reading D-5 and D-XE RTL sources -- InOutRes<>0 does block almost^(1) nothing.
It is not compatible with BP7, and may be incompatible with current Delphi way.
So the therm "Delphi-[in]compatible" should be refined to something like ">=ver", "<=ver" etc, and the target D-version should be set.

^(1) D-XE aborts some incomplete text output, namely in _WriteSpaces(), if error is encountered.

Bart Broersma

2016-12-14 18:16

reporter   ~0096780

program test;

{$apptype console}
{$I-}

var
  TF: Text;
begin
  Assign(TF,'nonexisting');
  writeln('Before append');
  Append(TF);
  writeln('After append');
  writeln(TF);
  writeln('After write to file');
end.

C:\Users\Bart\LazarusProjecten\ConsoleProjecten>dcc32 test.pas
Borland Delphi Version 15.0
Copyright (c) 1983,2002 Borland Software Corporation
...

C:\Users\Bart\LazarusProjecten\ConsoleProjecten>test
Before append
After append
After write to file

C:\Users\Bart\LazarusProjecten\ConsoleProjecten>fpc test.pas
Free Pascal Compiler version 3.0.0 [2015/11/16] for i386
...

C:\Users\Bart\LazarusProjecten\ConsoleProjecten>test
Before append

If memory serves me well, the in the TP era if IOResult <> 0, then an IO operation would cause a RTE.
I'll test in TP 6.0

Bart Broersma

2016-12-14 18:25

reporter   ~0096781

> If memory serves me well, the in the TP era if IOResult <> 0, then an IO
> operation would cause a RTE.

Memory failure ;-)

TP 6.0 behaves (with the above example from note 0096780) exactly the same as FPC 3.0.0.

Michael Van Canneyt

2016-12-14 18:51

administrator   ~0096786

Adapted the documentation.

Issue History

Date Modified Username Field Change
2016-12-13 12:08 Thaddy de Koning New Issue
2016-12-13 12:08 Thaddy de Koning Status new => assigned
2016-12-13 12:08 Thaddy de Koning Assigned To => Michael Van Canneyt
2016-12-13 12:22 Thaddy de Koning Note Added: 0096737
2016-12-13 12:52 Jonas Maebe Note Added: 0096738
2016-12-13 13:07 Thaddy de Koning Note Added: 0096739
2016-12-13 13:11 Thaddy de Koning Note Edited: 0096739 View Revisions
2016-12-13 13:13 Jonas Maebe Note Added: 0096740
2016-12-13 13:52 Thaddy de Koning Note Added: 0096741
2016-12-13 14:04 Jonas Maebe Note Added: 0096742
2016-12-13 17:51 Sergei Gorelkin Note Added: 0096746
2016-12-13 18:44 Max Nazhalov Note Added: 0096747
2016-12-13 18:47 Max Nazhalov Note Edited: 0096747 View Revisions
2016-12-13 22:07 Sergei Gorelkin Note Added: 0096751
2016-12-13 22:14 Jonas Maebe Note Added: 0096752
2016-12-13 23:47 Sergei Gorelkin Note Added: 0096757
2016-12-13 23:54 Jonas Maebe Note Added: 0096758
2016-12-14 07:58 Thaddy de Koning Note Added: 0096763
2016-12-14 08:00 Thaddy de Koning Note Edited: 0096763 View Revisions
2016-12-14 11:02 Sergei Gorelkin Note Added: 0096765
2016-12-14 12:31 Max Nazhalov Note Added: 0096767
2016-12-14 18:16 Bart Broersma Note Added: 0096780
2016-12-14 18:25 Bart Broersma Note Added: 0096781
2016-12-14 18:51 Michael Van Canneyt Fixed in Revision => 1375
2016-12-14 18:51 Michael Van Canneyt Note Added: 0096786
2016-12-14 18:51 Michael Van Canneyt Status assigned => resolved
2016-12-14 18:51 Michael Van Canneyt Fixed in Version => 3.1.1
2016-12-14 18:51 Michael Van Canneyt Resolution open => fixed
2016-12-14 18:51 Michael Van Canneyt Target Version => 3.2.0