What APIs is Affected by {$ IOCHECKS OFF}?

We have some ancient Delphi code (perhaps it even appeared as Turbo Pascal code) that uses {$I-} , aka {$ IOCHECKS OFF} , which makes use of the IOResult code instead of exceptions for disk I / O errors.

I want to get rid of {$I-} and pass this code in the 1990s, but for this I would like to know what {$IOCHECKS OFF} affects everything. Does this only appear to be on the hard old built-in I / O functions such as AssignFile / Reset / Rewrite / Append / CloseFile? Or does this affect more modern things like TFileStream? More importantly, what else could be affected that I don’t think about? (The basics of Delphi suggests that it also affects MkDir and RmDir. If this affects them, there should be more.)

The Delphi 2007 help section, "Verifying Output (Delphi) Output" ( ms-help://borland.bds5/devcommon/compdirsinput_outputchecking_xml.html ) says that this affects the “input / output procedure [s]” and that “the procedure I / O is described in the Delphi Language Guide. " This doesn't help much, since CodeGear never posted a Language Guide, and the last time Borland posted it was Delphi 5.

What functions and classes behave differently under {$I-} ?


EDIT: The accepted answer gives an excellent background, but here is a brief summary in the form of a list in alphabetical order: {$IOCHECKS OFF} affects only the following procedures from the system unit.

  • Append
  • Blockread
  • Blockwrite
  • Chdir
  • Closefile
  • Eof
  • Eoln
  • Erase
  • Filepos
  • FileSize
  • Flush
  • Mkdir
  • Read
  • Readln
  • Rename
  • Reset
  • Rewrite
  • Rmdir
  • Look for
  • Seekeof
  • Seekeoln
  • SetLineBreakStyle
  • Crop
  • Record
  • Writeln
+4
source share
1 answer

Since $I is a compiler directive, it can only affect code generated by the compiler, and can only affect code that actually compiles.

For two reasons, it cannot affect things like TFileStream . This is a class in Classes.pas, which is a unit that you are not compiling. Any code in it does not depend on the $I directive. In addition, the compiler does not specifically refer to this class. This is just another class.

The $I directive affects the built-in language features that you mentioned. The compiler generates calls to these functions on purpose. It also affects write , writeln and readln . It should also affect BlockRead and BlockWrite .

You can check the source code. Everything that causes SetInOutRes is susceptible to $I This includes functions that open files ( Append , Reset and Rewrite ), as well as anything that accepts a parameter of type file or TextFile ( Flush , BlockRead , BlockWrite , Erase , FilePos , Seek , FileSize , Read , readln , write , writeln , Rename , Eof , SeekEof , Eoln , SeekEol , Truncate , SetLineBreakStyle and CloseFile ). In addition, everything that causes InOutError ( ChDir , ChDir , amd RmDir ).

Noticeably absent from the AssignFile list. This function does not actually perform I / O. It simply sets up a file entry so that Append , Reset and Rewrite know what to do.


I must point out that looking at the source code is just a conclusion. The $I directive determines whether the compiler will insert calls to the __IOTest function in your own code after calling some other functions. This function checks the value of InOutRes , and if it is not equal to zero, a runtime error occurs (which may lead to an exception if SysUtils is included in your program). We cannot check the source code to directly find out which functions are affected by $I (since it is only called in the code generated by the compiler), so we really just look for which functions we install InOutRes on the assumption that they will not worry about it, if they don’t know that the compiler will check it after that.

+5
source

All Articles