Recent

Author Topic: WriteStr() with a non existing enum value will break Write()  (Read 1251 times)

prof7bit

  • Full Member
  • ***
  • Posts: 163
WriteStr() with a non existing enum value will break Write()
« on: October 23, 2023, 02:09:44 pm »
WriteStr() or Write() or WriteLn() with a non existing enum value will break all Write() for the rest of the program or until WriteStr() or Write() is used with an existing enum again.

Consider the following minimal program:

Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. {$IOChecks off}
  4.  
  5. type
  6.   TFoo = (
  7.     FOO_A = 0,
  8.     FOO_B = 1,
  9.     FOO_Z = 25
  10.   );
  11.  
  12. var
  13.   E: TFoo;
  14.   S: String;
  15.  
  16. begin
  17.   WriteLn('FPC Version: ' + {$I %FPCVersion});
  18.  
  19.   // This enum value does not exist!
  20.   E := TFoo(2);
  21.   WriteLn('Value is ', Ord(E));
  22.  
  23.   // This will break Write() for the rest of the program
  24.   WriteStr(S, E);
  25.   WriteLn(S);
  26.   Writeln('WriteLn() is broken now!');
  27.  
  28.   WriteStr(S, 42);
  29.   Writeln(S); // still broken
  30.  
  31.   WriteStr(S, 'XYZ');
  32.   Writeln(S); // still broken
  33.  
  34.   // WriteStr() with an existing enum value will "fix" it again
  35.   WriteStr(S, TFoo(0));
  36.   Writeln(S);
  37.   Writeln('WriteLn() is working again');
  38. end.
  39.  

The output of the above is:

Code: [Select]
FPC Version: 3.2.3
Value is 2
FOO_A
WriteLn() is working again

Is this intended behavior? I doubt it!

« Last Edit: October 23, 2023, 02:26:00 pm by prof7bit »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12000
  • FPC developer.
Re: WriteStr() with a non existing enum value will break Write()
« Reply #1 on: October 23, 2023, 02:24:36 pm »
It might be worth reporting.  Doing such operations on enums with gaps is not defined, but that doesn't mean error behaviour can't be improved.

Kays

  • Hero Member
  • *****
  • Posts: 614
  • Whasup!?
    • KaiBurghardt.de
Re: writeStr with a non‑existing enumeration value will break write
« Reply #2 on: October 23, 2023, 03:06:03 pm »
[…] Is this intended behavior? […]
This is a user error. The documentation of {$IOChecks} states:
Quote
The effect of this is that IOResult must be checked after each I/O operation for subsequent I/O operations to succeed.
It says “must be checked.” If you insert a call to system.IOResult after each potentially failing I/O operation, subsequent I/O operations remain unaffected.
Yours Sincerely
Kai Burghardt

Handoko

  • Hero Member
  • *****
  • Posts: 5386
  • My goal: build my own game engine using Lazarus
Re: writeStr with a non‑existing enumeration value will break write
« Reply #3 on: October 23, 2023, 03:42:46 pm »
This is a user error.
+1

Programmers should test the program before releasing it. That includes tests with range check and IO check on.
« Last Edit: October 23, 2023, 03:44:22 pm by Handoko »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12000
  • FPC developer.
Re: WriteStr() with a non existing enum value will break Write()
« Reply #4 on: October 23, 2023, 03:45:54 pm »
Hmm, I also think Kays has the right of it.  If write() raises an error it must be cleared. Somehow the second write enum clears the error ?

prof7bit

  • Full Member
  • ***
  • Posts: 163
Re: writeStr with a non‑existing enumeration value will break write
« Reply #5 on: October 23, 2023, 04:03:58 pm »
If you insert a call to system.IOResult after each potentially failing I/O operation, subsequent I/O operations remain unaffected.

This is the solution. So it is indeed intended behavior and I was unaware of this part of the documentation. A call to IOResult will fix my problem. Thank you!

 

TinyPortal © 2005-2018