На какие API влияют {$IOCHECKS OFF}?
У нас есть некоторый древний код Delphi (возможно, даже возникший как код Turbo Pascal), который использует {$I-}
ака {$
IOCHECKS
OFF}
, что заставляет код использовать IOResult вместо исключений для ошибок дискового ввода-вывода.
Я хочу избавиться от {$I-}
и перенести этот код в 1990-е годы, но для этого я хотел бы знать, на что все это влияет {$IOCHECKS OFF}
, Влияет ли это только на грубые старые встроенные функции ввода-вывода, такие как AssignFile / Reset / Rewrite / Append / CloseFile? Или это влияет на более современные вещи, такие как TFileStream? Что еще более важно, что еще может быть затронуто, о чем я не думаю? ( Основы Delphi предполагают, что он также влияет на MkDir и RmDir. Если он влияет на них, их должно быть больше.)
Раздел справки Delphi 2007 "Проверка ввода-вывода (Delphi)" (ms-help://borland.bds5/devcommon/compdirsinput_outputchecking_xml.html
) говорит, что это влияет на "процедуры ввода-вывода [s]" и что "процедуры ввода-вывода описаны в руководстве по языку Delphi". Это не очень помогает, так как CodeGear никогда не выпускал Language Guide, а последний раз Borland выпускал Delphi 5.
Какие функции и классы ведут себя по-разному под {$I-}
?
РЕДАКТИРОВАТЬ: принятый ответ дает некоторое хорошее представление, но вот краткое резюме в форме списка в алфавитном порядке: {$IOCHECKS OFF}
влияет только на следующие подпрограммы из системного блока.
- присоединять
- BlockRead
- BlockWrite
- ChDir
- CloseFile
- Eof
- Eoln
- стирать
- FilePos
- Размер файла
- Промывать
- MkDir
- Читать
- ReadLn
- переименовывать
- Сброс
- перезапись
- RmDir
- Искать
- SeekEof
- SeekEoln
- SetLineBreakStyle
- усекать
- Написать
- Writeln
1 ответ
Поскольку $I
является директивой компилятора, она может влиять только на код, сгенерированный компилятором, и она может влиять только на код, который фактически компилируется.
По этим двум причинам это не может повлиять на такие вещи, как TFileStream
, Это класс в Classes.pas, который вы не компилируете. На любой код в нем не влияет $I
директивы. Кроме того, компилятор не обрабатывает этот класс специально каким-либо образом. Это просто еще один обычный класс.
$I
Директива влияет на встроенные функции языка, которые вы упомянули. Компилятор генерирует вызовы этих функций специально. Это также влияет на звонки write
, writeln
, а также readln
, Это также должно повлиять BlockRead
а также BlockWrite
,
Вы можете проверить исходный код. Все, что звонит SetInOutRes
подвержен $I
, Это включает в себя функции, которые открывают файлы (Append
, Reset
, а также Rewrite
), а также все остальное, что принимает параметр типа file
или же TextFile
(Flush
, BlockRead
, BlockWrite
, Erase
, FilePos
, Seek
, FileSize
, Read
, Readln
, Write
, Writeln
, Rename
, Eof
, SeekEof
, Eoln
, SeekEol
, Truncate
, SetLineBreakStyle
, а также CloseFile
). Кроме того, все, что вызывает InOutError
(ChDir
, MkDir
, драм RmDir
).
Заметно отсутствует в списке AssignFile
, Эта функция на самом деле не выполняет никаких операций ввода-вывода. Он просто устанавливает запись файла так, чтобы Append
, Reset
, а также Rewrite
будет знать, что делать.
Я должен отметить, что смотреть на исходный код - это просто вывод. $I
директива контролирует, будет ли компилятор вставлять вызовы в __IOTest
Функция в вашем собственном коде после вызова некоторых других функций. Эта функция проверяет значение InOutRes
и, если он не равен нулю, возникает ошибка времени выполнения (что может привести к исключению, если SysUtils включен в вашу программу). Мы не можем проверить исходный код, чтобы напрямую узнать, на какие функции влияют $I
(так как он вызывается только в сгенерированном компилятором коде), поэтому мы действительно просто ищем, какие функции установлены InOutRes
с предположением, что они не будут делать это, если не будут знать, что компилятор проверит это позже.