哪些 API 会受到 {$IOCHECKS OFF} 的影响?

发布于 2024-07-26 19:12:29 字数 1564 浏览 7 评论 0原文

我们有一些古老的 Delphi 代码(甚至可能起源于 Turbo Pascal 代码),它使用 {$I-},又名 {$IOCHECKSOFF},这使得代码使用 IOResult 代替磁盘 I/O 错误的异常。

我想摆脱 {$I-} 并将此代码带入 1990 年代,但要做到这一点,我想知道 {$IOCHECKS 影响什么关闭}。 这是否只影响旧的内置 I/O 函数,如分配文件/重置/重写/追加/关闭文件? 或者它是否也会影响像 TFileStream 这样更现代的东西? 更重要的是,还有哪些我没有想到的可能受到影响的事情? (Delphi Basics 表明它也会影响 MkDir 和 RmDir。如果它影响那些,必须有更多。)

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

哪些函数和类在 {$I-} 下的行为有所不同?


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

  • Append
  • BlockRead
  • BlockWrite
  • ChDir
  • CloseFile
  • Eof
  • Eoln
  • Erase
  • FilePos
  • FileSize
  • Flush
  • MkDir
  • ReadReadln
  • 命名
  • Reset
  • Rewrite
  • RmDir
  • Seek
  • SeekEof
  • SeekEoln
  • SetLineBreakStyle
  • Truncate
  • Write
  • Writeln

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

I want to get rid of the {$I-} and bring this code forward into the 1990s, but to do that, I'd like to know what all is affected by {$IOCHECKS OFF}. Does this only affect the crufty old built-in I/O functions like AssignFile / Reset / Rewrite / Append / CloseFile? Or does it affect more modern things like TFileStream as well? More importantly, what else might be affected that I'm not thinking of? (Delphi Basics suggests that it also affects MkDir and RmDir. If it affects those, there have to be more.)

The Delphi 2007 Help topic "Input output checking (Delphi)" (ms-help://borland.bds5/devcommon/compdirsinput_outputchecking_xml.html) says that this affects "I/O procedure[s]", and that "I/O procedures are described in the Delphi Language Guide." This doesn't help much, since CodeGear has never shipped a Language Guide, and the last time Borland shipped one was Delphi 5.

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


EDIT: The accepted answer gives some great background, but here's the quick summary in alphabetized list form: {$IOCHECKS OFF} only affects the following routines from the System unit.

  • Append
  • BlockRead
  • BlockWrite
  • ChDir
  • CloseFile
  • Eof
  • Eoln
  • Erase
  • FilePos
  • FileSize
  • Flush
  • MkDir
  • Read
  • Readln
  • Rename
  • Reset
  • Rewrite
  • RmDir
  • Seek
  • SeekEof
  • SeekEoln
  • SetLineBreakStyle
  • Truncate
  • Write
  • Writeln

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

缘字诀 2024-08-02 19:12:29

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

由于这两个原因,它不能影响诸如TFileStream之类的东西。 它是 Classes.pas 中的一个类,这是一个您不编译的单元。 其中的任何代码都不受 $I 指令的影响。 此外,编译器不会以任何方式特殊对待该类。 这只是另一堂普通的课。

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

你可以检查一下源代码。 任何调用 SetInOutRes 的内容都容易受到 $I 的影响。 其中包括打开文件的函数(AppendResetRewrite),以及接受 类型参数的任何其他函数文件TextFile刷新BlockReadBlockWrite擦除 , FilePos, Seek, FileSize, 读取, Readln, 写入Writeln重命名EofSeekEofEolnSeekEolTruncateSetLineBreakStyleCloseFile)。 此外,任何调用 InOutErrorChDirMkDir、amd RmDir)的内容。

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


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

Since $I is a compiler directive, it can only affect compiler-generated code, and it can only affect code that actually gets compiled.

For those two reasons, it cannot affect things like TFileStream. It's a class in Classes.pas, which is a unit you don't compile. Any code in it is not affected by the $I directive. Furthermore, the compiler doesn't treat that class specially in any way. It's just another ordinary class.

The $I directive affects the language built-in functions that you've mentioned. The compiler generates calls to those functions specially. It also affects calls to write, writeln, and readln. It should also affect BlockRead and BlockWrite.

You can check the source code. Anything that calls SetInOutRes is susceptible to $I. That includes functions that open files (Append, Reset, and Rewrite), as well as anything else 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). Also, anything that calls InOutError (ChDir, MkDir, amd RmDir).

Notably absent from the list is AssignFile. That function doesn't actually do any I/O. It just sets up the file record so that Append, Reset, and Rewrite will know what to do.


I should point out that looking at the source code is just inference. The $I directive controls whether the compiler will insert calls to the __IOTest function in your own code after you call certain other functions. That function checks the value of InOutRes, and if it's not zero, it raises a run-time error (which may yield an exception if SysUtils is included in your program). We can't check the source code to directly find out what functions are affected by $I (since it's only called in compiler-generated code), so we're really just looking for which functions set InOutRes, with the assumption that they wouldn't bother doing that if they didn't know the compiler would check for it afterward.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文