![]() |
Initialisierung von result wird wegoptimiert
Hallo zusammen,
ich verwende folgendes Konstrukt:
Delphi-Quellcode:
Result soll erstmal false sein, und nur wenn in MachwasMit(MyObject) keine Exception aufgetreten ist, auf true gesetzt werden.
function irgendwas:boolean;
begin result:=false; // diese Zeile wird wegoptimiert MyObject:=TMyObject.Create; try MachwasMit(MyObject); result:=true; finally MyObject.Free; end; end; Das
Delphi-Quellcode:
wird aber wegoptimiert und ich bekomme für diese Zeile die Compilerwarnung
result:=false
H2007 Auf <Name der Function> zugewiesener Wert wird niemals benutzt. Bei einer Exception wäre also result undefiniert. Wenn ich aber eine Hilfsvariable einführe, compiliert es so, wie ich mir das vorstelle, und ich bekomme auch keine Compilerwarnung.
Delphi-Quellcode:
Wenn ich hier das ok:=false weglasse, bekomme ich sogar richtigerweise die Compilerwarnung
function irgendwas:boolean;
var ok:boolean; begin ok:=false; MyObject:=TMyObject.Create; try MachwasMit(MyObject); ok:=true; finally result:=ok; MyObject.Free; end; end; Variable OK ist möglicherweise nicht initialisiert worden. Wieso erkennt der Compiler bei der Verwendung der Hilfsvariablen, dass diese im try - finally - Block möglicherweise nicht initialisiert wird, bei Verwendung von result jedoch nicht? D2007 |
AW: Initialisierung von result wird wegoptimiert
Da die Exception durch das finally ja nicht abgefangen wird gelangt der Result-Wert auch nicht zum Aufrufer zurück. Insofern wird bei einer Exception der Result-Wert auch nie benutzt.
|
AW: Initialisierung von result wird wegoptimiert
Anders ausgedrückt: Wenn MachWasMit erfolgreich ist, bekommst du True zurück. Wenn MachWasMit fehlschlägt, bricht irgendwas ab. Die Methode gibt also immer True zurück oder schlägt fehl.
|
AW: Initialisierung von result wird wegoptimiert
Beim Zweiten wird es nicht wegoptimiert, da immer im Finally auf diese Variable zugegriffen wird.
Wenn es nicht knallt, dann der Wert von der Zuweisung im Try und wennes vorher knallte, dann die Initialzuweisung. Bei Zweitem muß die Initialisierung sogar vorhanden sein, da Finally das verwenden könnte (wenn es knall), auch wenn das Result danach wieder weggeworfen wird. Und beim ersten Beispiel, wird die initialisierung nie verendet (wenn es knallt, dann raucht es ab und keiner brauch das, und wenn es durchlief, dann wird immer nur das Letzte verwendet). |
AW: Initialisierung von result wird wegoptimiert
Hallo,
Zitat:
Delphi-Quellcode:
Übrigens ist es keine Compilerwarnung, sondern ein Hinweis.
function irgendwas:boolean;
begin Result:= False; // diese Zeile wird nicht mehr wegoptimiert try MyObject:=TMyObject.Create; try MachwasMit(MyObject); Result:= True; finally MyObject.Free; end; except // nu kommst du end; end; |
AW: Initialisierung von result wird wegoptimiert
Ich finde das Schachteln von zwei Try Blöcken in so einem Fall sehr unschön, und auch unnötig.
Try ... except ... end - und gleich danach ein free. Wenn man im Except Block keine Bocksprünge treibt, die ihrerseits wieder zu einer Exception führen können (und das sollte man ohnedies tunlichst vermeiden), wird auf diese Art das free auch ohne zweiten try-Block zuverlässig ausgeführt. |
AW: Initialisierung von result wird wegoptimiert
Hallo,
Einspruch Euer Ehren ;)
Delphi-Quellcode:
Das ist mir auch schon vorgekommen ...
procedure MachwasMit(AObject: TMyObject);
begin AObject.Free; end; function irgendwas:boolean; begin Result:= False; // diese Zeile wird nicht mehr wegoptimiert MyObject:=TMyObject.Create; try MachwasMit(MyObject); // hier wird das Objekt aus Versehen freigegeben Result:= True; except // nu kommst du end; MyObject.Free; // was passiert dann wohl hier? end; Das leere except end; sollte man natürlich mit einer sinnvollen Meldung (z.B. Logging) füllen. |
AW: Initialisierung von result wird wegoptimiert
Zitat:
|
AW: Initialisierung von result wird wegoptimiert
Zitat:
Zitat:
|
AW: Initialisierung von result wird wegoptimiert
Zitat:
In einem Computerspiel soll auf einen Klick auf Objekte reagiert werden. Um eine zuverlässige Response des Programms auf Mausklicks sicherzustellen, setzt die Onclick Routine nur eine boolean Variable clicked und kehrt sofort zurück, während eine timergesteuerte Routine die Objekte durchgeht und auf die Klicks dann wirklich reagiert. Eine mögliche Reaktion auf so einen Mausklick kann aber sein, das das Objekt als Ganzes gelöscht wird. Wenn der Spieler zweimal rasch hintereinander ein Objekt anklickt, dann kann es in extrem seltenen Fällen passieren, dass unmittelbar nach dem zweiten Start des Onclick die Timer-Routine dazwischen fährt und dem Onclick sein Objekt "unter den Füssen wegzieht", indem es das Objekt löscht. Dann führt clicked:=true (wie jeder andere Zugriffsversuch auf das Objekt) zu einer Exception, die man ganz einfach ignorieren kann, weil einen Klick auf ein Element, das ohnehin schon zum Löschen markiert war, braucht man nicht mehr zu berücksichtigen, und andere Exceptions sind an dieser Stelle absolut unplausibel. |
AW: Initialisierung von result wird wegoptimiert
Zitat:
Delphi-Quellcode:
prüfen, aber eben nicht jede Exception abfangen. Wie du schon sagst, kann man nur die Exceptions behandeln, die man vorhersehen kann. Alle anderen sollen dann aber auch irgendwie gemeldet werden - insbesondere dann, wenn sie absolut unplausibel sind, denn sonst würden sie ja zur ersten Gruppe gehören.
EAccessViolation
|
AW: Initialisierung von result wird wegoptimiert
EAccessViolation bedeuted in jedem Fall das der Programmierer irgend etwas falsch macht. Man kann sich nicht darauf verlassen das der Zugriff auf bereits freigegebene Objekte in jeder Situation diese Exception auslöst. Im schlimmsten Fall hat der Speichermanager den Speicherbereich bereits für ein neues Objekt bereitgestellt, das dann an dieser Stelle unvorhersehbar verändert oder gar freigegeben wird. Das führt zu weiteren Fehlern in anderen Programmteilen, die niemand finden oder korrigieren kann.
|
AW: Initialisierung von result wird wegoptimiert
Das wäre aber ein sehr hässliches Verhalten von Delphi, wenn bei einer Exception in einem try...finally-Konstrukt der Rückgabewert der Funktion verloren ginge. Einen vernünftigen Grund dafür gibt es nicht. Die übrigen Werte gehen ja auch nicht verloren, sonst könnte man den finally-Block gar nicht sinnvoll ausführen. In der Dokumentation steht das auch nicht.
Das bedeutet, dass man bei jeder unbekannten Funktion überprüfen müsste, ob sie überhaupt einen sinnvollen Wert zurückgibt. Sie könnte ja ein try...finally-Konstrukt enthalten. Das würde die ganze algorithmische Sicherheit auf den Haufen werfen, wäre also ein Totalschaden. Nein. Es gibt keine Ausrede für den Bug, dass Delphi den Rückgabewerte einer Funktion wegoptimiert bei einem try...finally-Konstrukt. |
AW: Initialisierung von result wird wegoptimiert
Zitat:
![]() Zitat:
Probier es doch einfach mal aus. |
AW: Initialisierung von result wird wegoptimiert
Ich habe nicht daran gedacht, dass das finally-Konstrukt die Exception im aufrufenden Programm nicht verhindert.
|
AW: Initialisierung von result wird wegoptimiert
Das bedeutet aber eigentlich, dass man eine Funktion mit try...finally-Konstruct in der aufrufenden Funktion/Prozedur immer in einem try...except-Konstrukt abfangen muss, wenn man verhindern will, dass das Programm sich unvorhergesehen benimmt. (Falls die aufgerufene Funktion dies nicht selber schon tut.)
|
AW: Initialisierung von result wird wegoptimiert
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:55 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