e-mail    Debatní kniha    Mapa stránek    Hlavní  
 perličky 
 

ON ERROR GOTO v TP 6.0 a 7.0

Slavomír Krasnický

Jde o obdobu příkazu známého z některých verzí Basicu. Princip řešení vychází z vlastností Turbo Pascalu a lze k němu dojít následující úvahou:

Je-li možné instalovat vlastní ukončovací proceduru (pomocí ExitProc:=@MyExit), která se provede po runtimovém erroru a na niž nejsou kladena nějaká omezení, pak se zdá být možné, aby program normálně pokračoval (samozřejmě ne po jakékoli chybě). Je totiž zřejmé, že před vyvoláním ukončovací procedury je obnoven obsah DS (globální proměnné a konstanty jsou přístupné) a že je ošetřen chybový stav po neúspěšné aritmetické operaci (další aritmetické operace se provádějí správně, ať už koprocesorem nebo jeho emulátorem). Nabízí se tedy možnost vložit do ExitProc ukazatel nikoli na proceduru, ale na návěští. Dojde-li k chybě, pak program pokračuje zde a zbývá už jen obnovit obsah registrů SP a BP. Z obsahu proměnných ExitCode a ErrorAddr lze zjistit příčinu chyby.
Z listingu je vidět, o co jde. Assembler je použit proto, že v Pascalu se nedá zjistit adresa návěští (operátor @, ani funkce Addr, Ofs a Seg nelze aplikovat na návěští). Pro uložení obsahu registrů SP a BP nelze použít lokální proměnné: ty se adresují právě přes SP a BP.

ON ERROR GOTO má rozumné použití zejména pro "zachycení" chyb při aritmetických operacích. Jde o chyby:

200: Division by zero 205: Floating point overflow 207: Invalid floating point operation 215: Arithmetic overflow error (jen TP 7.0 v režimu $Q+).

Např. procedura VAL (vstup čísla ze stringu) způsobí chybu 205, je-li číslo syntakticky v pořádku, ale příliš velké. Jiné chyby ("nearitmetické") bývají skutečně fatální, a nezbývá, než program ukončit.

{"ON ERROR GOTO ..."}

label
  err;

const
  exitsv: pointer = nil;
  SPsave:   word  = 0;
  BPsave:   word  = 0;

var
  pe:   record
          offs: word;
          segm: word;
        end;
  perr: pointer absolute pe;

begin
     {"perr:=@err", SPsave:=SP, BPsave:=BP}
     exitsv:=ExitProc;
     asm
       lea AX,err
       mov pe.offs,AX
       mov AX,CS
       mov pe.segm,AX
       mov SPsave,SP
       mov BPsave,BP
     end;
     ExitProc:=perr;

     {Kritický úsek programu, kde může dojít
      k chybě při numerickém výpočtu (Fatal
      errors 200, 205, 207, a 215 u TP 7.0,
      je-li nastaven režim $Q+)}

     {...}

     {Konec kritického úseku}
     ExitProc:=exitsv;

     {...}
     exit;

err: {Došlo k chybě v kritickém úseku}
  asm
    mov SP,SPsave
    mov BP,BPsave      {obnovení SP a BP}
  end;
  ExitProc:=exitsv;    {obnovení ExitProc}
  {Program teď může pokračovat
   jako by se nic nestalo.
   Z obsahu systémových proměnných
   ExitCode a ErrorAdr lze chybu
   identifikovat}

  {...}
end.



Pascal - hlavní
Překladače
Vlastní články
Převzaté články
Věci na stáhnutí
Odkazy k tématu
BP7 buglist
Chyba Run-time 200

BASIC