4

我们有一些古老的 Delphi 代码(甚至可能起源于 Turbo Pascal 代码)使用{$I-}, aka ,这使得代码使用IOResult而不是磁盘 I/O 错误的异常。{$IOCHECKS OFF}

{$I-}我想摆脱{$IOCHECKS OFF}. 这只影响像AssignFile/Reset/Rewrite/Append/CloseFile这样笨拙的旧内置I/O函数吗?或者它是否也会影响更现代的东西,比如 TFileStream?更重要的是,还有什么我没有想到的可能会受到影响?(Delphi Basics建议它也会影响 MkDir 和 RmDir。如果它影响那些,必须有更多。)

Delphi 2007 帮助主题“输入输出检查 (Delphi)”( ms-help://borland.bds5/devcommon/compdirsinput_outputchecking_xml.html) 指出这会影响“I/O 过程[s]”,并且“I/O 过程在 Delphi 语言指南中进行了描述”。这并没有多大帮助,因为 CodeGear 从未发布过语言指南,而 Borland 上一次发布语言指南是 Delphi 5。

哪些函数和类在 下表现不同{$I-}


编辑:接受的答案提供了一些很好的背景,但这里是按字母顺序排列的列表形式的快速摘要:{$IOCHECKS OFF} 影响系统单元中的以下例程。

  • 附加
  • 块读取
  • 块写
  • 目录
  • 关闭文件
  • Eof
  • 埃伦
  • 擦除
  • 文件位置
  • 文件大小
  • 冲洗
  • 目录
  • 阅读
  • 改名
  • 重置
  • 改写
  • 目录
  • 寻找
  • 搜索
  • 寻根
  • 设置LineBreakStyle
  • 截短
4

1 回答 1

5

由于$I是编译器指令,它只能影响编译器生成的代码,并且只能影响实际编译的代码。

由于这两个原因,它不会影响TFileStream. 它是Classes.pas中的一个类,它是一个你不编译的单元。其中的任何代码都不受该$I指令的影响。此外,编译器不会以任何方式特别对待该类。这只是另一个普通的班级。

$I指令会影响您提到的语言内置函数。编译器专门生成对这些函数的调用。write它还会影响对、writeln和的调用readln。它也应该影响BlockReadBlockWrite

您可以查看源代码。任何调用SetInOutRes都容易受到$I. 这包括打开文件的函数(AppendResetRewrite),以及任何其他接受类型参数fileTextFileFlushBlockReadBlockWriteEraseFilePosSeekFileSizeReadReadlnWriteWritelnRenameEofSeekEofEolnSeekEolTruncateSetLineBreakStyleCloseFile)的函数。此外,任何调用InOutError( ChDir, MkDir, amd RmDir) 的东西。

值得注意的是,列表中没有AssignFile. 该函数实际上并不执行任何 I/O。它只是设置文件记录,以便AppendResetRewrite知道该做什么。


我应该指出,查看源代码只是推理。该$I指令控制在您调用某些其他函数后,编译器是否会在您自己的代码中插入对该__IOTest函数的调用。该函数检查 的值,如果它不为零,则会引发运行时错误(如果SysUtils包含在您的程序中,则可能InOutRes会产生异常)。我们无法检查源代码以直接找出受哪些函数影响(因为它只在编译器生成的代码中调用),所以我们实际上只是在寻找哪些函数set,假设它们不会打扰如果他们不知道编译器会在之后检查它,那就这样做。$I InOutRes

于 2009-07-09T22:56:16.310 回答