На какие API влияют {$ IOCHECKS OFF}? - PullRequest
4 голосов
/ 10 июля 2009

У нас есть какой-то древний код 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} только влияет на следующие процедуры из системного блока.

  • Append
  • BlockRead
  • BlockWrite
  • ChDir
  • CloseFile
  • Eof
  • Eoln
  • Erase
  • FilePos
  • Flush
  • MkDir
  • Читать
  • ReadLn
  • Переименовать
  • Сброс
  • Перепишите
  • RmDir
  • Ищи
  • SeekEof
  • SeekEoln
  • SetLineBreakStyle
  • Округление
  • запись
  • Writeln

1 Ответ

5 голосов
/ 10 июля 2009

Поскольку $I является директивой компилятора, она может влиять только на код, сгенерированный компилятором, и может влиять только на код, который фактически компилируется.

По этим двум причинам не может влиять на такие вещи, как TFileStream. Это класс в Classes.pas , который вы не компилируете. На любой код в нем не распространяется директива $I. Кроме того, компилятор не обрабатывает этот класс специально каким-либо образом. Это просто еще один обычный класс.

Директива $I влияет на встроенные функции языка, о которых вы упомянули. Компилятор генерирует вызовы этих функций специально. Также влияет на звонки на номера write, writeln и readln. Это также должно повлиять на BlockRead и BlockWrite.

Вы можете проверить исходный код. Все, что вызывает SetInOutRes, восприимчиво к $I. Это включает в себя функции, которые открывают файлы (Append, Reset и Rewrite), а также все остальное, которое принимает параметр типа file или TextFile (Flush, BlockRead, * 1029). *, Erase, FilePos, Seek, FileSize, Read, Readln, Write, Writeln, Rename, Eof, SeekEof, Eoln, SeekEol, Truncate, SetLineBreakStyle и CloseFile). Кроме того, все, что вызывает InOutError (ChDir, MkDir, amd RmDir).

Заметно отсутствует в списке AssignFile. Эта функция на самом деле не выполняет никаких операций ввода-вывода. Он просто устанавливает запись файла так, чтобы Append, Reset и Rewrite знали, что делать.


Я должен отметить, что смотреть на исходный код - это просто вывод. Директива $I определяет, будет ли компилятор вставлять вызовы функции __IOTest в ваш собственный код после вызова некоторых других функций. Эта функция проверяет значение InOutRes и, если оно не равно нулю, вызывает ошибку времени выполнения (что может привести к исключению, если SysUtils включен в вашу программу). Мы не можем проверить исходный код, чтобы напрямую выяснить, на какие функции влияет $I (поскольку он вызывается только в сгенерированном компилятором коде), поэтому мы действительно просто ищем, какие функции set InOutRes, с предположением, что они не будут делать это, если не будут знать, что компилятор проверит это позже.

...