![]() |
Delphi-Version: XE
EDivByZero ohne Sysutils fangen
Hallo Zusammen!
Ich stehe gerade etwas auf dem Schlauch. Wieso fängt Delphi diese Exception nicht:
Delphi-Quellcode:
Na gut, das es ohne die Sysutils keine EDivByZero Exception gibt ist irgendwie klar, aber ich hätte trotzdem erwartete, dass ich im Except-Zweig lande.
program Project1;
{$APPTYPE CONSOLE} {$O-} //uses SysUtils; //Ohne Kommentar funktioniert es wunderbar :O var d: Integer; begin try d := 0; d := d div d; except writeln('Wer haette es gedacht ...'); end; readln; end. Gibt es eine Möglichkeit, Delphi davon zu Überzeugen, die Exception auch ohne Sysutils im Except-Block zu fangen? SEH per Hand (fs[0] ...), SetUnhandledExceptionFilter oder AddVectoredExceptionHandler würde ich gerne vermeiden. Schönen Gruß, Win32.API |
AW: EDivByZero ohne Sysutils fangen
Bei dem Code wird die Division wegoptimiert.
|
AW: EDivByZero ohne Sysutils fangen
Im Release-Modus mit
Delphi-Quellcode:
schon, ich meine aber eigentlich den Debug-Modus mit
{$O+}
Delphi-Quellcode:
.
{$O-}
|
AW: EDivByZero ohne Sysutils fangen
Hast du mal Breakpoints gesetzt?
So kannst du ja ganz leicht feststellen ob und was da wegoptimiert wurde oder auch nicht. Mach halt im Zweifelsfall mal ein writeln(d); hinter die Division. |
AW: EDivByZero ohne Sysutils fangen
Du meinst writeln(d); ;)
|
AW: EDivByZero ohne Sysutils fangen
Öhm.. ja, richtig! :oops:
|
AW: EDivByZero ohne Sysutils fangen
Mit
Delphi-Quellcode:
wird nichts "wegoptimiert". Darum geht es hier aber auch nicht, es geht auch nicht darum, ob der Quelltext so Sinn macht oder nicht. Die Frage ist wieso verweigert der Exception-Handler den Dienst, wenn ich die Sysutils nicht einbinde.
{$O-}
Edit: Das Problem ist, dass die Exception geworfen wird, aber der Exception-Handler diese nicht fängt. Das Programm stürzt also ohne Sysutils ab (Projekt 1 funktioniert nicht mehr ...). |
AW: EDivByZero ohne Sysutils fangen
Vermutlich weil die SysUtils nicht nur die Exceptionklassen bereitstellt, sondern auch noch so Einiges für die Exception-Behandlung initialisieren/einbinden.
Ohne SysUtils wird bei dieser Exception ein Zitat:
Die Behandlung bricht also sofort ab und das war's dann, da die Exception unbehandelt bis in System durchgerauscht ist. |
AW: EDivByZero ohne Sysutils fangen
Zitat:
Zitat:
|
AW: EDivByZero ohne Sysutils fangen
Delphi-Quellcode:
Ohne SysUtils ladet man dort und mit SysUtils wird stattdessen für bekannte Fehler die entsprechende Exception ausgelöst.
procedure RunErrorAt(ErrCode: Integer; ErrorAtAddr: Pointer);
begin ErrorAddr := ErrorAtAddr; _Halt(ErrCode); end; |
AW: EDivByZero ohne Sysutils fangen
Zitat:
Zitat:
|
AW: EDivByZero ohne Sysutils fangen
Zitat:
Stichwort wäre hier: SetExceptionMask |
AW: EDivByZero ohne Sysutils fangen
IMHO initialisiert Delphi die FPU mit Exceptions. SetExceptionMask liegt leider in der Math.pas die Sysutils.pas importiert. Ein direktes Aufrufen von
Delphi-Quellcode:
bringt aber leider auch keine Besserung.
Set8087CW($1372)
|
AW: EDivByZero ohne Sysutils fangen
Zitat:
Zitat:
|
AW: EDivByZero ohne Sysutils fangen
Dieser Handler bekommt von der Exception leider auch nichts mit, außerdem ist er global, was ich nach wie vor gerne vermeiden würde.
|
AW: EDivByZero ohne Sysutils fangen
Zitat:
Es ist eine System-Exception und keine Delphi-Exception. Ohne SysUtils keine Delphi-Exceptions und ohne Delphi-Exceptions (also die Objekte, welche ein Nachfahre von der Klasse Exception sind), gibt es auch keine Try-Except/Finally-Behandlung. Die System-Exception für
Delphi-Quellcode:
hat den Fehlercode 200, welches nach TRuntimeError reDivByZero gemapt wird.
div 0
Mit eingebundener SysUtils wird dann reDivByZero abgefangen und stattdessen eine Exception EDivByZero ausgelöst.
Delphi-Quellcode:
{ RTL error handler }
procedure ErrorHandler(ErrorCode: Byte; ErrorAddr: Pointer); export; var E: Exception; begin case ErrorCode of Ord(reOutOfMemory): E := OutOfMemory; Ord(reInvalidPtr): E := InvalidPointer; Ord(reDivByZero)..Ord(High(TRuntimeError)): begin with ExceptMap[ErrorCode] do E := ExceptTypes[EClass].Create(EIdent); end; else E := CreateInOutError; end; raise E at ErrorAddr; end; const ExceptTypes: array[TExceptType] of ExceptClass = ( EDivByZero, ERangeError, ...); ExceptMap: array[Ord(reDivByZero)..Ord(High(TRuntimeError))] of TExceptRec = ( (EClass: etDivByZero; EIdent: SDivByZero), (EClass: etRangeError; EIdent: SRangeError), ...); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz