AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Schutzblöcke überflüssig!?

Ein Thema von stahli · begonnen am 30. Sep 2020 · letzter Beitrag vom 1. Okt 2020
Antwort Antwort
Seite 1 von 5  1 23     Letzte »    
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#1

Schutzblöcke überflüssig!?

  Alt 30. Sep 2020, 14:39
Mal eine ketzerische Behauptung...
Ich möchte das ganz gern mal diskutieren, weil ich immer wieder auf Schutzblöcke stoße, die ich für unnötig halte...
Vermutlich stehe ich da wieder ziemlich allein, aber der Sinn von generellen Schutzblöcken um alle erzeugten Objekte erschließt sich mir einfach nicht...
Ich halte Schutzblöcke im Allgemeinen für völlig überflüssig, außer dort, wo bestimmte Fehler ausdrücklich erwartbar sind:


Folgender Code wird niemals einen Fehler produzieren:
Delphi-Quellcode:
obj1 := nil;
obj2 := nil;
obj3 := nil;

Beep;

obj1 := TObject.Create;
obj2 := TObject.Create;
obj3 := TObject.Create;

Beep;

obj1.Free;
obj2.Free;
obj3.Free;
Wenn doch, liegt das an irgendeinem Hardwareproblem oder Compilerfehler, der von der eigenen Software nicht beeinflussbar ist.
Insofern ist es völlig unsinnig, die Objektfreigaben in einen finally-Abschnitt zu packen.

Der Code wird viel länger und unübersichtlicher und es gibt überhaupt keinen wirklichen Nutzen.

Bei mehreren verschachtelten Schutzblöcken wird es immer unübersichtlicher.


Delphi-Quellcode:
obj1 := nil;
obj2 := nil;
obj3 := nil;

try
  Beep;

  obj1 := TObject.Create;
  obj2 := TObject.Create;
  obj3 := TObject.Create;
  try
    Beep;
  except
    // Exception handling
  end;
finally
  obj1.Free;
  obj2.Free;
  obj3.Free;
end;
Die Ausstattung des Codes mit Schutzblöcken erzeugt also mehr Aufwand und verringert die Übersichtlichkeit.

Während der gesamten Laufzeit der Anwendung wird das Programm mit 99,99999%iger Sicherheit an diesen Stellen niemals eine Exception werfen.

Die Schutzblöcke sind hier also völlig überflüssig.


Natürlich gibt es auch Fälle, wo Schutzblöcke etwas nachvollziehbarer sind.

Wenn wir jetzt in dem Code statt Beep eine Funktion DivHundretBy(X: Integer)aufrufen und dort verschiedene Werte DivHundretBy(Random(10)) übergeben, erhalten wir irgendwann bei den Tests den Laufzeitfehler "Division durch Null".

Während der Programmentwicklung ist es erst mal egal, dass die zuvor erzeugten Objekte beim Stopp der Anwendung nicht freigegeben wurden.
Das ist absolut unerheblich.

Wir werden den Fehler nun bereinigen. Je nach Bedarf wird ausgeschlossen, dass die Funktion mit 0 ausgerufen wird DivHundretBy(Random(9)+1) oder es gibt eine andere Behandlung dieses Sonderfalles.

Danach können wir wieder sehr sicher sein, dass die Berechnung fehlerfrei (ohne werfen einer Exception) funktionieren wird und der Finally-Abschnitt ist wieder verzichtbar. Wir werden so oder so niemals eine Exception erhalten und die Objekte werden immer korrekt freigegeben und die berechneten Werte stimmen (Programm arbeitet fehlerfrei).


Wenn man während der Projektentwicklung solch eine Problemstelle übersehen hat und der Endanwender eine Exception-Meldung erhält, muss der Fehler natürlich schnellstmöglich bereinigt werden.
Ob die 3 o.g. Objekte in dem Moment freigegeben werden oder nicht, ist nebensächlich.
Das wäre nur interessant, wenn im Sekundentakt tausende neue Speicherlecks entstehen und aufgeräumt werden müssten.
Im Grunde kann der Anwender mit dem Programm so oder so erst mal nicht mehr sinnvoll arbeiten, weil man erst mal nicht einschätzen kann, ob der Datenbestand überhaupt noch konsistent ist oder nicht.

Hier steht halt dringend eine Fehlerbereinigung aus, aber ob die 3 Objekte nun noch freigegeben wurden oder nicht, spielt keine wirkliche Rolle.
Jedenfalls sehe ich den Aufwand, den Code dagegen mit try...finally um alle Objekterzeugungen und Freigaben zuzupflastern als völlig unverhältnismäßig an.

Da ist mir schlanker, funktionierender Code deutlich lieber.
Die Fehlerbereinigung muss identisch durchgeführt werden.



Natürlich gibt es auch Fälle, wo immer mit einem Problem gerechnet werden muss, dass man selbst nicht beeinflussen kann. Als Beispiel gäbe es da Erzeugen von Ordnern, Netzwerkunterbrechungen, Zugriffsfehler auf Dateien o.ä.
In den Fällen macht es natürlich schon Sinn, mit Schutzblöcken zu arbeiten und z.B. Speicherbereiche direkt wieder frei zu geben.
Das sehe ich dann aber als "geplanten Ablauf der Anwendung" an. Es gehört halt zu Anwendung dazu, dass z.B. ein Ordner nicht erstellt werden kann oder eine Verbindung unterbrochen wird. Wenn man das Problem nicht zuvor selbst auschließen kann (wie z.B. bei einer Division durch Null), dann kann man zumindest auf den Problemfall gezielt reagieren und einen Programmablauf vorsehen.


Aber Schutzblöcke generell um Objekterzeugungen halte ich in den allermeisten Fällen für unnötig.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.070 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Schutzblöcke überflüssig!?

  Alt 30. Sep 2020, 14:45
Einfach nur Nein!
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Schutzblöcke überflüssig!?

  Alt 30. Sep 2020, 14:48
Würde ich auch sagen.

Wo soll man anfangen? Es gäbe so vieles, das man erwidern könnte...

Mobile Anwendungen - wenn auch nur eine Exception nach draußen zum Betriebssystem gelangt, ist das der Moment, in dem die App kommentarlos beendet wird. Als Entwickler mag man Werkzeuge haben, um die Logfiles einzusehen - der normale Anwender steht auf dem Schlauch.

Innerhalb eines Except- oder Finally-Blocks hast Du (je nach Situation) durchaus die Chance, die Anwendung wieder in einen kontrollierten und kontrollierbaren Zustand zu bringen und so zu retten. Deiner Aussage, dass eine Anwendung im Falle einer Exception grundsätzlich verloren ist, mag ich so pauschal nicht zustimmen.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.354 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Schutzblöcke überflüssig!?

  Alt 30. Sep 2020, 14:57
Ich programmiere seit Turbo-Pascal 3.0 (und vorher mit Basic). Also ca. 40 Jahre.

Damals gab es keine Schutzblöcke und man musste einfach an alle möglichen Fehlerfälle denken. So programmiere ich auch heute noch. Dennoch ergeben Schutzblöcke Sinn. Es ist auch für den Anwender besser, wenn dieser eine sinnvolle Fehlermeldung bekommt und das Programm trotz einer Exception nicht abstürzt. Die Speicherlecks sind da meistens noch relativ unwichtig. Der Anwender wird froh sein, dass trotz eines Programmfehlers seine Bearbeitung mit dem Programm nicht verloren geht. Ohne Schutzblöcke sähe das völlig anders aus.

Ich denke, dass man es in beide Richtungen übertreiben kann.
Peter
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Schutzblöcke überflüssig!?

  Alt 30. Sep 2020, 14:59
Hallo,
Zitat:
Folgender Code wird niemals einen Fehler produzieren:
Wenn der Code innerhalb der Methode (Methode2) eines Objektes ausgeführt wird, Beep eine Methode des Objektes ist und die anderen 3 Variablen ausserhalb des Objektes definiert sind, puhhhh

Dann
Wenn das Objekt nicht erzeugt wird, sondern nur Methode2 aufgerufen wird, schmiert der Code beim Beep ab.
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#6

AW: Schutzblöcke überflüssig!?

  Alt 30. Sep 2020, 15:04
Zitat:
Folgender Code wird niemals einen Fehler produzieren
Abgesehn von den drei Compilerwarnungen.

Zitat:
Folgender Code wird niemals einen Fehler produzieren
Außer der Speicher ist voll
oder alles ist zu spät, dann isses sowieso egal. (Speichermanagement oder Stack zerballert)

Wenn mehr als TObject und es im Create knallen kann, dann fehlt die Freigabe der vorherrigen Objekte.


Mehrere Free in ein Finally nur, wenn es "normalerweise" nicht im Free/Destroy knallen kann.
(Fälle wo die Anwendung eh nicht mehr lauffähig ist, ignoriere ich ... z.B. Speichermanagement/Stack total kaputt)


Aber ja, teilweise optimiere ich auch das Eine oder Andere Try-Finally weg
und verwende ein gemeinsames Finally oder die Zeile nach einem Try-Except (ohne Re-Raise),
bzw. wenn "nachweißlich" im Create/Destroy nichts passieren kann, gleich alles weg.


Zitat:
Mobile Anwendungen - wenn auch nur eine Exception nach draußen zum Betriebssystem gelangt,
Auch Windows macht es so.
OK, wobei die VCL/FMX und (schlimmernoch) TThread viele Exceptions vom System fern halten.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (30. Sep 2020 um 15:10 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.159 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Schutzblöcke überflüssig!?

  Alt 30. Sep 2020, 15:09
Natürlich gibt es auch Fälle, wo immer mit einem Problem gerechnet werden muss, dass man selbst nicht beeinflussen kann. Als Beispiel gäbe es da Erzeugen von Ordnern, Netzwerkunterbrechungen, Zugriffsfehler auf Dateien o.ä.
Falls es dich interessiert, schau mal wie das bei Java gelöst ist- Da kompiliert der Code gar nicht erst wenn du eine "zu erwartende" Exception nicht behandelst (z.B. Datei nicht gefunden usw.). Entweder du behandelst die Exception oder du markierst deine Methode so, dass man bei ihrer Benutzung ebendiese Exception zu erwarten hat. Und der Aufrufer deiner Methode muss es diese Exception dann behandeln.

Das vermisse ich an Java am meisten...
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Schutzblöcke überflüssig!?

  Alt 30. Sep 2020, 15:29
Mobile Anwendungen - wenn auch nur eine Exception nach draußen zum Betriebssystem gelangt, ist das der Moment, in dem die App kommentarlos beendet wird. Als Entwickler mag man Werkzeuge haben, um die Logfiles einzusehen - der normale Anwender steht auf dem Schlauch.

Innerhalb eines Except- oder Finally-Blocks hast Du (je nach Situation) durchaus die Chance, die Anwendung wieder in einen kontrollierten und kontrollierbaren Zustand zu bringen und so zu retten. Deiner Aussage, dass eine Anwendung im Falle einer Exception grundsätzlich verloren ist, mag ich so pauschal nicht zustimmen.
Das ist ja etwas anderes. Eine Fehlermeldung auszugeben und eine Fehlerbereinigung (Datenbereinigung) durchzuführen ist ja in Ordnung.
Aber nur
Delphi-Quellcode:
try
  ObjektErzeugen;
  EtwasTun;
finally
  ObjektFreigeben;
end;
Halte ich für unnütz. Da wird keine Fehlernachricht ausgegeben und keine Fehlerbehandlung durchgeführt (außer die Speicherfreigabe).

Allerdings weiß ich nicht, wie sensibel mobile Apps gehändelt werden müssen. Ich hatte nur Windowsanwendungen im Blick.


Hallo,
Zitat:
Folgender Code wird niemals einen Fehler produzieren:
Wenn der Code innerhalb der Methode (Methode2) eines Objektes ausgeführt wird, Beep eine Methode des Objektes ist und die anderen 3 Variablen ausserhalb des Objektes definiert sind, puhhhh

Dann
Wenn das Objekt nicht erzeugt wird, sondern nur Methode2 aufgerufen wird, schmiert der Code beim Beep ab.
So ganz kann ich jetzt nicht folgen. Aber solche Probleme würdest Du doch beim Testen Deiner Anwendung finden und bereinigen.
Wenn das oder das zutrifft ... das sind m.E. Kriterien, mit den die Anwendung umgehen können muss.
Wenn später Sonderfälle entdeckt werden, die noch unbehandelt sind, muss das natürlich nachgebessert werden. Aber ob die drei Objekte sofort mit dem Werfern der Exception aufgelöst werden oder nicht, macht doch keinen Unterschied.
Deine Anwendung läuft nach der Fehlermitteilung weiter und greift weiter auf die Speicherstellen zu, die noch die richtigen oder falsche Daten enthalten. Entweder läuft das Programm mit richtigen oder falschen Daten weiter oder es gibt weitere Exceptions.
Ich sehe da keinen Vorteil, dass die Speicher der drei Objekte zuvor freigegeben wurden.

Natürlich gibt es auch Fälle, wo immer mit einem Problem gerechnet werden muss, dass man selbst nicht beeinflussen kann. Als Beispiel gäbe es da Erzeugen von Ordnern, Netzwerkunterbrechungen, Zugriffsfehler auf Dateien o.ä.
Falls es dich interessiert, schau mal wie das bei Java gelöst ist- Da kompiliert der Code gar nicht erst wenn du eine "zu erwartende" Exception nicht behandelst (z.B. Datei nicht gefunden usw.). Entweder du behandelst die Exception oder du markierst deine Methode so, dass man bei ihrer Benutzung ebendiese Exception zu erwarten hat. Und der Aufrufer deiner Methode muss es diese Exception dann behandeln.

Das vermisse ich an Java am meisten...
Das kenne ich nicht, klingt aber ganz gut. Es sind halt Sonderfälle, mit denen irgendwie umgegangen werden muss. Zumindest ist mit so etwas immer zu rechnen.

Dein letzter Satz passt nicht. Vermisst Du sowas in Delphi?
Soweit würde ich übrigens nicht gehen wollen. Wenn die Anwendung sicher stellt, dass z.B. ein Order "A" oder Ordner "B" erzeugt werden kann, dann muss man m.E. dafür keine Exceptionbehandlung erzwingen. Der Programmierer sollte aber aus eignem Interesse hier eine einrichten, wenn ein entsprechendes Problem vermutlich mal auftreten kann.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.093 Beiträge
 
Delphi 12 Athens
 
#9

AW: Schutzblöcke überflüssig!?

  Alt 30. Sep 2020, 15:35
Delphi-Quellcode:
procedure LebenswichtigeFunktion_SelfDriveCar_Ausweichmanöver;
begin
try
  ObjektErzeugen;
  EtwasTun;
finally
  ObjektFreigeben;
end;
end;

...
...
...

procedure MainLoop;
begin

    while True
    begin

        if ObjektVoraus then
        begin
            LebenswichtigeFunktion_SelfDriveCar_Ausweichmanöver;
        end;

    end;

end;

<== Wenn es crasht (z.B. out-of-memory) ohne try-finally fliegt es raus, OHNE Kontrolle
<== Mit try-finally hat man die Chance das es beim 2ten Mal noch funktiniert
Die Frage ist doch eher, wie wichtig ist die Sicherheit in deiner App ?
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Schutzblöcke überflüssig!?

  Alt 30. Sep 2020, 15:52
Delphi-Quellcode:
procedure MainLoop;
begin
...
            LebenswichtigeFunktion_SelfDriveCar_Ausweichmanöver;
...
end;

<== Wenn es crasht (z.B. out-of-memory) ohne try-finally fliegt es raus, OHNE Kontrolle
<== Mit try-finally hat man die Chance das es beim 2ten Mal noch funktiniert
Die Frage ist doch eher, wie wichtig ist die Sicherheit in deiner App ?

Das wäre so ein oben beschriebener Fall, dass im Sekundentakt neue Probleme auftauchen. Das könnte man als Sonderfall ansehen - wobei dann neben der Speicherfreigabe auch wieder eine echte Fehlerkorrektur erfolgen müsste, damit das Sinn macht.

Wie gesagt, es ging mir um reine Objektfreigabe im Finallyblock ohne Loop und ohne wirkliche Fehlerbehandlung.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 5  1 23     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:18 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz