Che tutte le API sono affetti da {$ IOCHECKS OFF}?
-
12-09-2019 - |
Domanda
Abbiamo un po 'antico codice Delphi (potrebbe avere anche origine come codice di Turbo Pascal) che utilizza {$I-}
, alias {$
IOCHECKS
OFF}
, il che rende il codice uso IOResult invece di eccezioni per disco I / O errors.
Voglio sbarazzarsi del {$I-}
e portare questo codice in avanti nel 1990, ma per fare questo, mi piacerebbe sapere che cosa tutto è affetto da {$IOCHECKS OFF}
. Questo influisce solo il crufty vecchio built-in funzioni di I / O come AssignFile / Reset / riscrittura / Aggiunta / CloseFile? O influisce cose più moderni come TFileStream come bene? Ancora più importante, che altro potrebbero essere interessati che non sto pensando? ( Delphi Basics suggerisce che colpisce anche MkDir e RmDir. Se colpisce quelli, ci devono essere più.)
L'argomento della Guida "uscita di ingresso di controllo (Delphi)" Delphi 2007 (ms-help://borland.bds5/devcommon/compdirsinput_outputchecking_xml.html
) dice che questo influenza "Procedura di I / O [s]", e che "I / O procedure sono descritte nella Guida Delphi lingua." Questo non aiuta molto, dal momento che CodeGear ha mai spedito una Guida linguistica, e l'ultima volta Borland spedito era Delphi 5.
Quali funzioni e le classi si comportano diversamente in {$I-}
?
Modifica La risposta accettata dà qualche grande sfondo, ma ecco il riassunto rapido sotto forma di lista in ordine alfabetico:. {$IOCHECKS OFF}
solo riguarda le seguenti routine della unità di sistema
- Append
- BlockRead
- BlockWrite
- ChDir
- CloseFile
- Eof
- Eoln
- Cancella
- FilePos
- FileSize
- Scala
- MkDir
- Leggi
- readLn
- Rinomina
- Ripristina
- Riscrivere
- RmDir
- Seek
- SeekEof
- SeekEoln
- SetLineBreakStyle
- Tronca
- Scrivi
- Writeln
Soluzione
Dato $I
è una direttiva del compilatore, può interessare solo il codice generato dal compilatore, e può colpire solo il codice che in realtà viene compilato.
Per questi due motivi, non può influenzare le cose come TFileStream
. Si tratta di una classe in Classes.pas , che è un'unità non si compila. Qualsiasi codice in esso non è influenzato dalla direttiva $I
. Inoltre, il compilatore non considera quella classe specialmente in alcun modo. E 'solo un'altra classe ordinaria.
La direttiva $I
colpisce le funzioni linguistiche integrate che che hai citato. Il compilatore genera chiamate a tali funzioni appositamente. Colpisce anche le chiamate verso write
, writeln
e readln
. Essa dovrebbe anche interessare BlockRead
e BlockWrite
.
È possibile controllare il codice sorgente. Tutto ciò che chiama SetInOutRes
è suscettibile di $I
. Ciò include funzioni che aprono i file (Append
, Reset
, e Rewrite
), così come qualsiasi altra cosa che accetta un parametro di tipo file
o TextFile
(Flush
, BlockRead
, BlockWrite
, Erase
, FilePos
, Seek
, FileSize
, Read
, Readln
, Write
, Writeln
, Rename
, Eof
, SeekEof
, Eoln
, SeekEol
, Truncate
, SetLineBreakStyle
, e CloseFile
). Inoltre, tutto ciò che chiama InOutError
(ChDir
, MkDir
, amd RmDir
).
In particolare assente dalla lista è AssignFile
. Tale funzione in realtà non fa alcun I / O. Esso definisce solo il record file in modo che Append
, Reset
, e Rewrite
saprà cosa fare.
Vorrei sottolineare che guardando il codice sorgente è solo l'inferenza. La direttiva $I
controlla se il compilatore inserirà chiamate alla funzione __IOTest
nel proprio codice dopo che si chiama alcune altre funzioni. Tale funzione controlla il valore di InOutRes
, e se non è zero, genera un errore di run-time (che può produrre un'eccezione se SysUtils è incluso nel programma). Non possiamo controllare il codice sorgente per direttamente scoprire quali funzioni sono influenzati da $I
(dal momento che è chiamato solo nel codice generato dal compilatore), quindi siamo davvero solo alla ricerca di quali funzioni set InOutRes
, con il presupposto che non avrebbero preoccuparsi di fare che se non sapevano il compilatore avrebbe verificare la presenza di essa in seguito.