Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Schutzblöcke überflüssig!? (https://www.delphipraxis.net/205633-schutzbloecke-ueberfluessig.html)

stahli 30. Sep 2020 13:39

Schutzblöcke überflüssig!?
 
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.

TiGü 30. Sep 2020 13:45

AW: Schutzblöcke überflüssig!?
 
Einfach nur Nein!

Daniel 30. Sep 2020 13:48

AW: Schutzblöcke überflüssig!?
 
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.

Jasocul 30. Sep 2020 13:57

AW: Schutzblöcke überflüssig!?
 
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.

hoika 30. Sep 2020 13:59

AW: Schutzblöcke überflüssig!?
 
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.

himitsu 30. Sep 2020 14:04

AW: Schutzblöcke überflüssig!?
 
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.

Der schöne Günther 30. Sep 2020 14:09

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von stahli (Beitrag 1474591)
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...

stahli 30. Sep 2020 14:29

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von Daniel (Beitrag 1474596)
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.


Zitat:

Zitat von hoika (Beitrag 1474599)
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.

Zitat:

Zitat von Der schöne Günther (Beitrag 1474605)
Zitat:

Zitat von stahli (Beitrag 1474591)
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.

Rollo62 30. Sep 2020 14:35

AW: Schutzblöcke überflüssig!?
 
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 ?

stahli 30. Sep 2020 14:52

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von Rollo62 (Beitrag 1474607)
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.

freimatz 30. Sep 2020 15:26

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von stahli (Beitrag 1474591)
Während der gesamten Laufzeit der Anwendung wird das Programm mit 99,99999%iger Sicherheit an diesen Stellen niemals eine Exception werfen.

Nein es sind nur 99,98% :P

Bei meinem Code sind schutzblöcke meistens unnötig - weil ich wo immer möglich Interfacereferencen verwende.
Ansonsten verwende ich die immer! Selbst wenn es technisch nicht nötig sein sollte, würde es meine Gewohnheit reduzieren, die dazu führt dass ich nicht mal einen vergesse.

Ghostwalker 30. Sep 2020 16:28

AW: Schutzblöcke überflüssig!?
 
Naja..so generell kann man das glaub ich nicht wirklich sagen, das Schutzblöcke überflüssig sind.
Es kommt wirklich auf die Situation drauf an.

Z.b. wenn ich auf den Source der Klasse, dich ich erzeugen möchte, keinen Zugriff hab (Stichwort: Komponenten von Dritt-Anbietern), dann kann ein Schutzblock nicht wirklich
schaden.

Wenn ich dagegen die Klasse selbst geschrieben hab, würd ich das eher weglassen, grad während der Entwicklung. Bei Entwicklungen im Team sie es wieder ganz anders aus.

Es gibt da denk ich viele Gründe für und gegen Schutzblöcke

himitsu 30. Sep 2020 16:39

AW: Schutzblöcke überflüssig!?
 
Zitat:

Entweder du behandelst die Exception oder du markierst deine Methode so, dass ....
Im XMLDoc/DocumentationInsight kann man zu erwartende Exceptions angeben, aber der Compiler beachtet sowas nicht.

Nur im HelpInsight wird dem Entwickler sowas dann angezeigt, falls er dort reinguckt.

Zitat:

Dein letzter Satz passt nicht. Vermisst Du sowas in Delphi?
Wenn er im Delphi ist, dann vermisst er das, was er von Java kennt.


Zitat:

Das wäre so ein oben beschriebener Fall, dass im Sekundentakt neue Probleme auftauchen
Sowas kann man selbst teilweise behandeln.
Bei uns sind nahezu alle Komponenten abgeleitet.
Somit war es z.B. ein Leichtes in TTimer eine Behandlung einzufügen die nach x Fehlern den Timer disabled und eine letzte Fehlermeldung anzeigt, damit nicht millionen Fehlermeldungen aufploppen.

PS: Im OnPaint Fehlermeldungen anzuzeigen ist eine super Idee. :zwinker:
Fehler kommt und der wird angezeigt, Dialog ploppt auf, das Fenster bekommt spätestens beim Schließen des Dialogs mit, dass es neu gezeichnet werden muß und schon tritt der Fehler wieder auf ... Endlosschleife.
Hier also nur Loggen und/oder die Komponente auf Invisible stellen (und dannach notfalls das Programm beenden, bzw. das Fenster schließen).

Delphi.Narium 30. Sep 2020 17:04

AW: Schutzblöcke überflüssig!?
 
Der wissenschaftliche Beweis, dass man fehlerfreie Software schreiben kann, steht noch aus.

Und solange bleiben bei mir die Schutzblöcke drin.

Auch wenn ich von meinem Code (in Ausnahmefällen) absolut sicher sein kann, dass da keine Fehler drinne sind und ich von daher keine Fehler erwarte, bleiben die Schutzblöcke drinne, derweil: Auch mit meiner Erwartung kann ich gehörig schief liegen.

Bei jedem Objekt, dass ich erstelle, besteht die (theoretische) Möglichkeit, dass die Erstellung scheitert. Also muss das abgesichert werden. Und, egal welcher (erwartete oder unerwartete) Fehler auftritt, es spricht nichts dagegen, vorsorglich ein gesichertes Aufräumen zu implementieren.

Am schlechtesten sind die Fehler zu finden, die bei der unstrukturierten Behandlung von Fehlern in der Fehlerbehandlung auftreten, die nur deshalb passieren, weil man an der fehlerverursachenden Stelle vergaß (oder es fahrlässig für überflüssig hielt) für eine geordnete Weiterverarbeitung im Programm zu sorgen.

Oder ein ganz grober Vergleich:

Im Auto verzichtet man auch nicht auf das Anschnallen, den Airbag, die Knautschzone, nur weil man sicher ist, dass man gut und sicher autofahren kann und keinen Unfall baut.

Die Probleme kommen auch für 'nen perfekten Autofahrer häufig von außen.

Und bei Software sind dieses Außen z. B. Betriebssystem, Hardware, Compiler, Bios, (Anwender sollen zuweilen auch dazu gehören ;-)), ..., die ggfls. auch (vermeintlich) fehlerfreie Software an den obskursten Stellen ins Straucheln bringen können. Und hier versuche ich durch 'ne (hoffentlich) vernünftige "Prophylaxe" möglichen Problemen aus dem Weg zu gehen.

Schutzblöcke gehören da selbstverständlich zu.

freimatz 30. Sep 2020 17:29

AW: Schutzblöcke überflüssig!?
 
Amen, Basta, ...

Zitat:

Zitat von stahli (Beitrag 1474591)
Mal eine ketzerische Behauptung...
Aber Schutzblöcke generell um Objekterzeugungen halte ich in den allermeisten Fällen für unnötig.

Doch noch eines: Ketzer werden heutzutage nicht mehr verbrannt, aber sie bekommen (zumindest bei mir) dafür Minuspunkte sollten sie sich um einen Job bewerben.

stahli 30. Sep 2020 17:47

AW: Schutzblöcke überflüssig!?
 
@Delphi.Narium

Wollen wir anhand Deines Beispiels mal weiter diskutieren?
Die Argumentation finde ich nämlich ganz passend. Vielleicht können wir ja irgendetwas draus ziehen...

Also das Beispiel mit dem Auto passt nicht ganz zu meinem Thema. Im Falle eines Unfalles helfen Gurt und Airbag, die Folgen zu mildern.
Bei der Software kann man die Analogie vielleicht bei einer Fehlerbeseitigung ziehen.
Die Funktion wird abgebrochen, der Speicherbereich wird aufgeräumt, der Anwender erhält eine Nachricht und kann mit einem konsistenten Datenbestand weiter arbeiten.
Soweit alles ok.


Was ich nicht nachvollziehen kann, ist folgendes:

Zitat:

Zitat von Delphi.Narium (Beitrag 1474626)
Der wissenschaftliche Beweis, dass man fehlerfreie Software schreiben kann, steht noch aus.

Und solange bleiben bei mir die Schutzblöcke drin.

...

Bei jedem Objekt, dass ich erstelle, besteht die (theoretische) Möglichkeit, dass die Erstellung scheitert. Also muss das abgesichert werden. Und, egal welcher (erwartete oder unerwartete) Fehler auftritt, es spricht nichts dagegen, vorsorglich ein gesichertes Aufräumen zu implementieren.

Am schlechtesten sind die Fehler zu finden, die bei der unstrukturierten Behandlung von Fehlern in der Fehlerbehandlung auftreten, die nur deshalb passieren, weil man an der fehlerverursachenden Stelle vergaß (oder es fahrlässig für überflüssig hielt) für eine geordnete Weiterverarbeitung im Programm zu sorgen.

...

Schutzblöcke gehören da selbstverständlich zu.


Nehmen wir noch ein konkretes Beispiel:

Wir erzeugen zwei Personenobjekte und überweisen einen Betrag.

Delphi-Quellcode:
procedure Überweisung;
begin
  Person1 := TPerson.Create;
  Person1.LoadFromDB;
  Person2 := TPerson.Create;
  Person2.LoadFromDB;
  Person1.Überweise(Person2, 100);
  Person1.SaveToDB;
  Person2.SaveToDB;
  Person1.Free;
  Person2.Free;
end;
Hier können jetzt diverse Probleme auftreten.
Wenn man die zwei Free-Anweisungen jetzt in einen Finally-Block setzt - ohne sonstige Fehlerbehandlung - findest Du weder den Fehler besser noch ist Dein Datenbestand besser geschützt noch erhält der Anwender bessere Fehlerinformationen.
Nur der Speicherplatz der zwei Objekte wird wieder freigegeben. Der Aufrufer der Prozedur Überweisung weiß nichts von dem Fehler und das Programm geht davon aus, dass alles passt.

Ob die Überweisung in der Datenbank realisiert wurde oder nicht, kann Dein Programm nicht nachvollziehen und der Anwender schon gar nicht.

Dass der Speicherplatz der zwei Objekte freigegeben wurde hilft auch niemandem - jedenfalls sehe ich dafür keinen sachlichen Grund.

Noch einmal: Eine Fehlerbehandlung und Benachrichtigung im Sinne "Überweisung ist fehlgeschlagen - bitte wiederholen! Der bisherige Datenbestand wurde nicht beeinträchtigt!" ist völlig korrekt. In dem Zusammenhang natürlich auch die Freigabe der erzeugten Objekte.


Aber alle Objektfreigaben in Schutzblöcke zu kapseln, ohne eine wirkliche Fehlerbehandlung zu realisieren - das halte ich für überflüssig.
Und oft wird ja so argumentiert, dass Objekte immer in Schutzblöcke gehören.

Ich sehe dafür einfach keinen sachlichen Grund.


@freimatz

Wenn man das so gewöhnt ist und machen möchte - ok.
Einen Nutzen sehe ich darin aber nicht (und habe auch noch kein überzeugendes Argument gehört).

Delphi.Narium 30. Sep 2020 18:26

AW: Schutzblöcke überflüssig!?
 
Hoffentlich hab' ich Dich nicht falsch verstanden.

Deine Argumentation klingt im Moment für mich in etwa so (sehr grob formuliert):

Wenn ich keine vernüftige Fehlerbehandlung habe, kann ich mir im Fehlerfalle auch die Freigabe von Objekten sparen.

Die Prozeduren bei Dir wären bei mir schonmal Funktionen, die im Erfolgsfalle ein True zurückgeben, im Fehlerfalle ein False. Wenn die erste Funktion fehlschlägt, wird die zweite nicht mehr ausgeführt. Welchen Sinn hätte es denn, wenn eine der beiden Personen nicht aus der DB geladen werden könnte, die Überweisung durchzuführen? Und dann das Ergebnis auch noch speichern?

Meiner Meinung nach ist Dein Beispiel schon logisch grob falsch, von daher halte ich anhand eines derartigen Beispiels eine Diskussion über die Sinnhaftigkeit von Schutzblöcken für nicht angebracht.

Oder mal wieder sehr dreist formuliert:

Wer so schlecht programmiert, kann sich auch Schutzblöcke sparen, die machen den Kohl dann auch nicht mehr fett.


Zitat:

Zitat von freimatz
... aber sie bekommen (zumindest bei mir) dafür Minuspunkte sollten sie sich um einen Job bewerben.

Da würd' ich noch etwas weiter gehen: Hätten bei mir keine Chance, einen Job zu bekommen.

PS:

Das Autothema passt sehr gut.

Du argumentierst
Zitat:

Also das Beispiel mit dem Auto passt nicht ganz zu meinem Thema.
nämlich in der Begründung für das Nichtpassen im Zusammenhang mit Schutzblöcken, durch die Einführung von Schutzblöcken,
Zitat:

Im Falle eines Unfalles helfen Gurt und Airbag, die Folgen zu mildern.
dass es nicht passt.

Durch die Einführung dessen, dessen Nutzen Du bezweifelts, widerlegst Du ein Beispiel für den Sinn dessen, was Du bezweifelts?

Ehrlich gesagt: Auf so eine Diskussion hab' ich keine Lust.

stahli 30. Sep 2020 18:44

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1474634)
Deine Argumentation klingt im Moment für mich in etwa so (sehr grob formuliert):

Wenn ich keine vernüftige Fehlerbehandlung habe, kann ich mir im Fehlerfalle auch die Freigabe von Objekten sparen.

Die Prozeduren bei Dir wären bei mir schonmal Funktionen, die im Erfolgsfalle ein True zurückgeben, im Fehlerfalle ein False. Wenn die erste Funktion fehlschlägt, wird die zweite nicht mehr ausgeführt. Welchen Sinn hätte es denn, wenn eine der beiden Personen nicht aus der DB geladen werden könnte, die Überweisung durchzuführen? Und dann das Ergebnis auch noch speichern?

Meiner Meinung nach ist Dein Beispiel schon logisch grob falsch, von daher halte ich anhand eines derartigen Beispiels eine Diskussion über die Sinnhaftigkeit von Schutzblöcken für nicht angebracht.

...

Ehrlich gesagt: Auf so eine Diskussion hab' ich keine Lust.

Einmal kurz antworten will ich dennoch.

Wenn man (in möglichen Fehlerfällen) Rückgabewerte nutzt und den Programmablauf entsprechend steuert, ist das völlig in Ordnung (das Beispiel hatte ich ich auch gebracht). Das ist auch nicht der Ansatz, den ich kritisiert habe.

Ohne Fehlerbehandlung ist die Freigabe von Objekten im Fehlerfall nebensächlich - genau das UND NUR DAS meine ich.

Delphi.Narium 30. Sep 2020 18:55

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von stahli
Ohne Fehlerbehandlung ist die Freigabe von Objekten im Fehlerfall nebensächlich - genau das UND NUR DAS meine ich.

deckt sich mit dem
Zitat:

Zitat von Delphi.Narium
Wer so schlecht programmiert, kann sich auch Schutzblöcke sparen, die machen den Kohl dann auch nicht mehr fett.

Aber ehrlich: Ist eine Diskussion darüber, ob man bei schlechter bzw. fehlerhafter Programmierung Schutzblöcke nutzen soll oder nicht, wirklich zielführend?

himitsu 30. Sep 2020 18:56

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1474626)
Oder ein ganz grober Vergleich:

Im Auto verzichtet man auch nicht auf das Anschnallen, den Airbag, die Knautschzone, nur weil man sicher ist, dass man gut und sicher autofahren kann und keinen Unfall baut.

Es kommt nur auf die Definition drauf an.

In Deutschland kommt demnächst vermutlich ein neuer französischer Kleinstwagen auf den Markt
und dort wird kein Airbag eingebaut und für Knautschzone ist sowieso kein Platz ... du mußt dir nur eine passende Begründungen ausdenken, dann passt es schon. :zwinker:
* der ist so langsam, da passiert schon nichts
* und falls dir ein SUV oder LKW reinrauscht, dann ist eh alles egal

Das Ding ist unter Anderem auch für Jugendliche ab 16/17 Jahren gedacht (Motoradführerschein A1)
und die fahren bekanntlich sooo sicher und routiniert, dass da keine Unfälle zu erwarten sind.



Bezüglich Fehlerbehandlung oder Rückgaben auswerten
https://www.delphipraxis.net/205581-...ehandlung.html

Delphi.Narium 30. Sep 2020 19:25

AW: Schutzblöcke überflüssig!?
 
Der verlinkte Thread zeigt ja, dass es diverse Ursachen für
Zitat:

Der wissenschaftliche Beweis, dass man fehlerfreie Software schreiben kann, steht noch aus.
gibt.

Man kann selbst noch so gut, gewissenhaft, sicher und (hoffentlich) fehlerfrei programmieren. Man weiß nun mal nicht, ob die genutzten Bibliotheken, Compiler, ... absolut fehlerfrei sind, ob alle genutzen Betriebssystemfunktionen fehlerfrei sind, ...

Also wird versucht das "eigene Zeugs" so zu schreiben, dass man bei allen Fehlern, bei denen man erahnt, dass sie passieren könnten, eine sichere Fehlerbehandlung, eine sichere Freigabe von Resourcen, ... implementiert.

Und ja: Die Implemetierung all dessen ist aufwändig, wenn man Pech hat macht's sogar den größten Teil der Programmierung aus.

jaenicke 30. Sep 2020 19:36

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von stahli (Beitrag 1474630)
Hier können jetzt diverse Probleme auftreten.
Wenn man die zwei Free-Anweisungen jetzt in einen Finally-Block setzt - ohne sonstige Fehlerbehandlung - findest Du weder den Fehler besser noch ist Dein Datenbestand besser geschützt noch erhält der Anwender bessere Fehlerinformationen.
Nur der Speicherplatz der zwei Objekte wird wieder freigegeben. Der Aufrufer der Prozedur Überweisung weiß nichts von dem Fehler und das Programm geht davon aus, dass alles passt.

Doch, denn es geht ja um den Fall, dass eine Exception ausgelöst wird, so dass die Freigabe des Objekts übersprungen würde, weil man bei der Exception heraus springt. Dann kann die Exception zwar abgefangen werden, aber der Speicher wird nicht freigegeben.

Und nun nehmen wir mal an der Code wird in einem Programm immer wieder aufgerufen, das länger läuft, z.B. ein Webservice... da ist dann irgendwann trotz sauberer Behandlung der Exceptions der Speicher voll.

Wenn es nur um wenige Aufrufe geht, merkt man in der Tat nicht viel davon. Aber das Programm benutzt eben mehr Speicher als nötig.

Noch schlechter wird es, wenn man in dem Objekt ein Handle auf eine Datei offen hat oder ähnliches, so dass die Datei dann gesperrt bleibt bis das Programm beendet wird.

Und damit man das nicht immer neu bewerten muss, macht es Sinn einfach immer eine korrekte Behandlung solcher potentiellen Probleme einzubauen. Denn sonst müsstest du ja bei jeder Änderung schauen, ob deine Prozedur nicht irgendwo aufgerufen wird, wo dann eine Behandlung nötig wird...

Davon abgesehen bringt ein Ressourcenschutzblock nur etwas, wenn er auch korrekt aufgebaut ist (Konstruktoraufruf vor dem try, sonst springt man bei einer Exception im Konstruktor auch in das finally obwohl die Variable noch gar nicht zugewiesen ist und dann knallt es ggf. dort erneut):
Delphi-Quellcode:
procedure Run;
begin
  obj1 := TObject.Create;
  try
    Beep;
    obj2 := TObject.Create;
    try
      obj3 := TObject.Create;
      try
        Beep;
      finally
        obj3.Free;
      end;
    finally
      obj2.Free;
    end;
  finally
    obj1.Free;
  end;
end;

try
  Run;
except
  on E: Exception do
  begin
    WriteLog(E);
    UserDialog(Format('Interner Fehler: %s - %s', [E.ClassName, E.Message]));
  end;
end;

himitsu 30. Sep 2020 20:03

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von jaenicke (Beitrag 1474639)
Konstruktoraufruf vor dem try, sonst springt man bei einer Exception im Konstruktor auch in das finally obwohl die Variable noch gar nicht zugewiesen ist und dann knallt es ggf. dort erneut

Man könnte jetzt zwar denken
"ist doch nicht so schlimm, wenn es nochmal knallt ... der Nutzer bekommt ja dennoch nur einen Fehler zu sehen"
aber das stimmt nicht, denn er und ein eventuelles Logging bekommt nur den letzten Fehler zu sehen und die "eigentliche" Fehlermeldung und Position ist dann weg, was echt blöd für die Fehlersuche ist.
Das ist genauso schlimm, wie wenn man im Except den Fehler abfängt und den Fehlertext durch einen sinnlosen und nichtssagenden Text ersetzt.

Und da die Vairale nicht initialisiert ist, kann sie sonstwo hinzeigen,
wodurch dann das Free nochmal richtig was im Speicher zerstören kann, und somit die Funktion seines Programm dann richtig schädigen würde.

stahli 30. Sep 2020 20:16

AW: Schutzblöcke überflüssig!?
 
Ja, danke Sebastian.

Deinen Text kann ich nachvollziehen und da gehe ich auch weitestgehend mit.
Dein Beispiel ist grundsätzlich auch in Ordnung, da Du eine Exception auswertest und darauf reagierst.

Oft sieht man aber Beispiele wie Dein "Run" alleinstehend, wo die Objekte wieder freigegeben werden und keine Fehlerbehandlung ersichtlich ist.
Das finde ich dann halt unsinnig.


Folgenden Punkt Deiner Ausführungen sehe ich aber dann doch anders:

Zitat:

Zitat von jaenicke (Beitrag 1474639)
Und damit man das nicht immer neu bewerten muss, macht es Sinn einfach immer eine korrekte Behandlung solcher potentiellen Probleme einzubauen. Denn sonst müsstest du ja bei jeder Änderung schauen, ob deine Prozedur nicht irgendwo aufgerufen wird, wo dann eine Behandlung nötig wird...

Ich finde den Ansatz sinnvoller, mich dabei auf die potenziell problematischen Stellen zu beschränken.
Entweder weiß ich von vorn herein, dass an bestimmten Stellen ein Exception-Problem auftreten kann, das berücksichtigt werden muss oder ich merke es bei der Entwicklung bzw. in einer Testphase.
Wenn ich 1000 Stellen im Code mit Schutzblöcken absichere und nur eine ein wirkliches Risiko beinhaltet, dann finde ich den Aufwand einfach nicht zu rechtfertigen (zumal der Code auch schlechter wartbar wird).

Wenn das mögliche Problem in Deinem Beispiel nicht vermeidbar ist (z.B. Netzkabel gezogen) und Deine Exceptionbehandlung das Problem vollständig löst, so dass das Programm korrekt mit konsistenten Daten weiter arbeitet, dann ist die Lösung absolut sinnvoll.
Eine Datenbereinigung ist dort jedoch auch nicht skizziert, sondern nur ein Log und eine Infobox.

Wenn KEINE ausdrückliche Datenbereinigung erfolgt, dann muss vor einer Fortsetzung der Arbeit erst mal der Datenbestand gesichert/geprüft und der Fehler in der Software schnell bereinigt werden.
In dem Moment komme ich wieder zu dem Schluss, dass die finallys in dem Run völlig verzichtbar sind:

Dein Code wäre dann m.E. gleichwertig zu folgendem:

Delphi-Quellcode:
procedure Run;
begin
  obj1 := TObject.Create;
  Beep;
  obj2 := TObject.Create;
  obj3 := TObject.Create;
  Beep;
  obj3.Free;
  obj2.Free;
  obj1.Free;
end;

try
  Run;
except
  on E: Exception do
  begin
    // VollständigeDatenprüfungUndBereinigung;
    WriteLog(E);
    UserDialog(Format('Interner Fehler: %s - %s', [E.ClassName, E.Message]));
  end;
end;
Hier mal angenommen, der Fehler wäre nicht komplett ausgebügelt und der Datenbestand möglicherweise inkonsistent.
In beiden Fällen erhalten wir eine Info und einen Log aber wir wüssten nicht, was nun mit den Daten ist.
Der Fehler müsste bereinigt werden und das Programm ein Update erhalten.
Eine Weiterarbeit wäre dem Anwender nicht zu empfehlen, weil wir nichts über den Datenbestand sagen können.
Die verkürzte Run-Prozedur hätte keine wirklichen Nachteile gegenüber Deiner. Ok, da dümpeln noch 1 - 3 Speicherbereiche im Speicher rum, aber das Programm muss ja sowiso beendet werden.

Wenn da natürlich die VollständigeDatenprüfungUndBereinigung eingebaut wäre, dann wäre Deine Lösung perfekt und absolut richtig.


Fazit:
- Exceptionbehandlung mit Datenbereinigung -> Object.Free im Finally sinnvoll
- keine Exceptionbehandlung mit vollständiger Datenbereinigung -> Object.Free im Finally nicht hilfreich

Und vollständige Datenbereinigung bei möglichen Fehlern kann man nur bei erwarteten bzw. denkbaren Fehlern durchführen.

freimatz 30. Sep 2020 20:53

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von stahli (Beitrag 1474641)
Entweder weiß ich von vorn herein, dass an bestimmten Stellen ein Exception-Problem auftreten kann, das berücksichtigt werden muss oder ich merke es bei der Entwicklung bzw. in einer Testphase.

Da fallen mir nun wirklich nur ironische Kommentare ein.

Zitat:

Zitat von stahli (Beitrag 1474641)
Wenn ich 1000 Stellen im Code mit Schutzblöcken absichere und nur eine ein wirkliches Risiko beinhaltet, dann finde ich den Aufwand einfach nicht zu rechtfertigen (zumal der Code auch schlechter wartbar wird).

Wenn dem so wäre ja. Aber es ist nicht so. Es sind nicht 1000.
Ein Block ist in 5 Sekunden gemacht. Die Fehler oder Memory-Leak suchen, weil irgendein so ein :roll::wall: mal gemeint hat auf einem Block verzichten zu können oder es vergessen hat, dauert teilweise Tage.

Delphi.Narium 30. Sep 2020 21:13

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von freimatz (Beitrag 1474643)
Zitat:

Zitat von stahli (Beitrag 1474641)
Entweder weiß ich von vorn herein, dass an bestimmten Stellen ein Exception-Problem auftreten kann, das berücksichtigt werden muss oder ich merke es bei der Entwicklung bzw. in einer Testphase.

Da fallen mir nun wirklich nur ironische Kommentare ein.

Habe schon viele Tester erlebt, richtig gute, die fanden Logikfehler durch passende Testdaten, auf die weder die Analysten noch die Entwickler je kamen.

Aber das die irgendwann mal ein Speicherleck gefunden haben, hab' ich nie erlebt.

stahli 30. Sep 2020 21:29

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von freimatz (Beitrag 1474643)
Da fallen mir nun wirklich nur ironische Kommentare ein.

Bitte bleib sachlich.

Wenn man z.B. mit Netzwerkverbindungen arbeitet muss man immer mit Abbrüchen rechnen und darauf reagieren.
An anderen Stellen wird aber doch mit getesteten Klassen und Bedingungen gearbeitet, wo keine Exceptions zu erwarten sind.
Wenn irgendwann doch Probleme erkannt werden, muss man eben doch nachbessern.

Das gehört für mich zu ordentlichen Tests.


Zitat:

Zitat von freimatz (Beitrag 1474643)
Ein Block ist in 5 Sekunden gemacht. Die Fehler oder Memory-Leak suchen, weil irgendein so ein :roll::wall: mal gemeint hat auf einem Block verzichten zu können oder es vergessen hat, dauert teilweise Tage.

Ich sage ja nicht, dass Speicher nicht freigegeben werden soll. Im Falle dass "ES KNALLT" (man also einen schwerwiegenden Fehler hat, das Programm nicht mehr sauber funktioniert und beendet werden sollte und die (gespeicherten) Daten möglicherweise sogar kaputt sind) ist es wurscht, ob vor dem Crash Speicher von 3 Objekten freigegeben wurde oder nicht.
Wenn es ordentlich gerumst hat wirst Du bestimmt nicht schauen, ob der Speicher zuvor korrekt aufgeräumt wurde.
Du musst den Fehler finden und das Programm sowie die Daten bereinigen.

Wenn das Programm korrekt läuft, werden alle Free ausgeführt und es gibt kein Speicherleck.
Nur wenn es unerwartet Knallt, würde ein solches entstehen - aber dann hat man sowieso deutlich größere Probleme.
Mit einer Problemlösung ist auch das Speicherleck automatisch wieder vom Tisch.


Ich verstehe nicht, dass Du (weitestgehenden) Verzicht auf Schutzblöcke mit Gleichgültigkeit gegenüber Speicherlecks gleichsetzt.
Das hat doch gar nichts miteinander zu tun.

Delphi.Narium 30. Sep 2020 22:52

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von stahli
Wenn man z.B. mit Netzwerkverbindungen arbeitet muss man immer mit Abbrüchen rechnen und darauf reagieren.
An anderen Stellen wird aber doch mit getesteten Klassen und Bedingungen gearbeitet, wo keine Exceptions zu erwarten sind.
Wenn irgendwann doch Probleme erkannt werden, muss man eben doch nachbessern.

Ich erwarte in meinen Programmen grundsätzlich keine Exceptions, schon garnicht nach ausreichenden Tests.

Die Schutzblöcke sind für die unerwarteten Fehler.

Wenn ich mit Netzverbindungen arbeite, dann wird dort, wo die Netzverbindung genutzt wird, eine Fehlerbehandlung implementiert, so dass von dort keine Exception "irgendwo ins Programm fliegen kann" und erst recht kein Programmzustand erreicht werden kann, bei dem eigentlich nur noch "ein Abschuß des Programmes" sinnvoll erscheint.

Zitat:

Zitat von stahli
Wenn es ordentlich gerumst hat wirst Du bestimmt nicht schauen, ob der Speicher zuvor korrekt aufgeräumt wurde.
Du musst den Fehler finden und das Programm sowie die Daten bereinigen.

Das ist ein Zustand, der bei meinen Programmen nicht auftreten darf und ich kann mich nicht erinnern, wann so ein Zustand zuletzt aufgetreten ist. Das dürfte Jahre her sein (bezogen auf den Produktivbetrieb). Beim Entwickeln und Testen kann's schonmal passieren und dann weiß ich, dass ich meinen Hausaufgaben nicht vernünftig gemacht habe.

Zitat:

Zitat von stahli
Wenn das Programm korrekt läuft, werden alle Free ausgeführt und es gibt kein Speicherleck

Stimmt, und mit Schutzblöcken kann ich mich sogar bei unerwarteten Fehlern darauf verlassen und nicht nur bei erwarteten.

Und ein Programm nach den Kriterien zu entwickeln, dass es im Extremfall egal ist, wenn was nicht freigegeben wird, ist mir zu kompliziert.

Meine Routinen sollen sowohl im Normalfall, als auch im Ausnahmefall, möglichst sauber arbeiten.

Aber irgendwie sind unsere Ansichten zu dem Thema sehr unterschiedlich. Also lassen wir es dabei.

stahli 30. Sep 2020 23:26

AW: Schutzblöcke überflüssig!?
 
Zwei Antworten möchte ich nochmal los werden (zum vielleicht besseren Verständnis):

Zitat:

Zitat von Delphi.Narium (Beitrag 1474649)
Das ist ein Zustand, der bei meinen Programmen nicht auftreten darf und ich kann mich nicht erinnern, wann so ein Zustand zuletzt aufgetreten ist. Das dürfte Jahre her sein (bezogen auf den Produktivbetrieb). Beim Entwickeln und Testen kann's schonmal passieren und dann weiß ich, dass ich meinen Hausaufgaben nicht vernünftig gemacht habe.

Genau das meine ich auch. Die Anwendung sollte so ausgerüstet sein, dass sie mit allen auftretenden Situationen umgehen kann.
Das muss sicher gestellt sein aber mehr ist nicht notwendig. Notfalls ist eine schnelle Nachbesserung erforderlich.


Zitat:

Zitat von Delphi.Narium (Beitrag 1474649)
Die Schutzblöcke sind für die unerwarteten Fehler.

...

Und ein Programm nach den Kriterien zu entwickeln, dass es im Extremfall egal ist, wenn was nicht freigegeben wird, ist mir zu kompliziert.
Meine Routinen sollen sowohl im Normalfall, als auch im Ausnahmefall, möglichst sauber arbeiten.

M.E. ist es einfacher, auf unnötige finally-Blöcke zu verziochten, wenn sie keinen tatsächlichen Nutzen haben.
Bei einem unerwarteten Fehler arbeitet Dein Programm ohnehin nicht mehr sauber - das geht grundsätzlich nicht.

Wenn es sich dagegen um ein erwartetes Problem handelt, das im Rahmen einer Exception behandelt und gelöst werden kann, dann ist es etwas völlig anderes - darum ging es mir aber nicht.


Insofern hat sich meine Einschätzung nicht geändert.
Aber danke für alle sachlichen Beiträge, auch wenn ich da mit der gängigen Einschätzung offenbar nicht überein stimme.


PS: Ich denke übrigens, dass ich ganz ordentlich und sauber programmiere (auch wenn ich kein Profi bin). Meine Programme laufen schon ganz zuverlässig und ohne Exceptions sowie die aktuelleren auch ohne Speicherlecks. :-)

himitsu 1. Okt 2020 00:44

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von freimatz (Beitrag 1474643)
Ein Block ist in 5 Sekunden gemacht.

0.1 Sekunden

tryf[enter] oder trye[enter] oder über das Refactoring "umgeben"




An extremeinfachen oder zeitkritischen Stellen z.B. "geziehlt" keine Fehlerbehandlung zu machen würde ich als "Ausnahme" ansehen.
Das überdenkt man und schaut genauer hin und es wird an der Stelle dann auch dokumentiert, damit sich niemand wundet, weil dort was zu fehlen scheint.

jaenicke 1. Okt 2020 05:44

AW: Schutzblöcke überflüssig!?
 
Ich frage mich vor allem wo die Motivation eigentlich liegt. Leider sehe ich es viel zu oft, dass auf Kosten der Lesbarkeit (zu kurze Variablennamen) oder Wartbarkeit (with) ein paar geschriebene Zeilen oder Zeichen im Quelltext gespart werden (oder eben um ein paar Mikrosekunden an unwichtigen Stellen zu sparen wie bei try..finally weglassen). Zeichen im Quelltext zu sparen ist aber so ziemlich der unwichtigste Punkt, den es überhaupt gibt und die Performance im Bereich von try..finally ist auch meistens egal...

Viel wichtiger ist doch, dass der Code robust ist (eben nicht z.B. nach Änderungen plötzlich Speicherlecks verursachen kann), wartbar, lesbar ist usw., wofür es eben Konventionen zur Codeformatierung und aber auch zum Schreiben von Code in der jeweiligen Sprache gibt. Und dazu gehören in Delphi auch die Ressourcenschutzblöcke.

Rollo62 1. Okt 2020 07:39

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von stahli (Beitrag 1474610)
Zitat:

Zitat von Rollo62 (Beitrag 1474607)
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.

Eben nicht:
Das passiert nur EINMAL, nach 12 Jahren Betrieb ...

Wegen sowas stürzen Flugzeuge ab :stupid:

stahli 1. Okt 2020 08:27

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von jaenicke (Beitrag 1474658)
Ich frage mich vor allem wo die Motivation eigentlich liegt. Leider sehe ich es viel zu oft, dass auf Kosten der Lesbarkeit (zu kurze Variablennamen)...

Das hat mit meinem Anliegen/meiner Nachfrage nichts zu tun.


Zitat:

Zitat von jaenicke (Beitrag 1474658)
Viel wichtiger ist doch, dass der Code robust ist (eben nicht z.B. nach Änderungen plötzlich Speicherlecks verursachen kann)...

Eine bessere Robustheit erkenne ich durch einen finally-Block ohne wirkliche Fehlerbehandlung eben nicht. Aber das habe ich schon mehrfach erläutert.


Zitat:

Zitat von Rollo62 (Beitrag 1474665)
Das passiert nur EINMAL, nach 12 Jahren Betrieb ...
Wegen sowas stürzen Flugzeuge ab :stupid:

Um in dem Beispiel zu bleiben: Das Flugzeug stürzt bereits ab, aber die Piloten räumen vor dem Aufschlag schnell noch die Küche auf.

Wie gesagt, das Programm läuft normalerweise stabil und alle Objekte werden immer freigegeben.
Nach 1 Jahr tritt ein unerkannter Fehlerfall auf, der Kunde ruft an und beschwert sich über eine Fehlermeldung und fragt, ob seine Daten noch stimmen. Dann muss das Problem geklärt werden. Ob Person.Free noch durchlaufen wurde oder nicht, interessiert da nicht wirklich - nur welche Daten noch geändert und gespeichert wurden und wie sichergestellt werden kann, dass der Fehler nicht wieder auftritt.



Aber wir kommen da halt nicht zusammen. Lassen wir es dabei.
Es sehe es ja nicht als schädlich an, so zu arbeiten, nur halt als unnötig.

TiGü 1. Okt 2020 08:47

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von stahli (Beitrag 1474630)

Delphi-Quellcode:
procedure Überweisung;
begin
  Person1 := TPerson.Create;
  Person1.LoadFromDB;
  Person2 := TPerson.Create;
  Person2.LoadFromDB;
  Person1.Überweise(Person2, 100);
  Person1.SaveToDB;
  Person2.SaveToDB;
  Person1.Free;
  Person2.Free;
end;

Bleiben wir mal bei diesem Beispiel von Seite 2.
Stelle dir vor, diese procedure läuft in einen Webserver bei einem Zahlungsdienstleister wie PayPal.

PayPal hat Millionen Kunden weltweit.

Jetzt nutzen 5000 Leute pro Stunde die Überweisungsfunktion.

Aus irgendeinen Grund schlägt LoadFromDB() oder Überweise() oder SaveToDB() fehl.
Der eigentliche Grund ist unerheblich.
Man kann es sich vorstellen, also wird es passieren.

Im schlimmsten Fall hast du dann 10000 TPerson-Instanzen pro Stunde, die dir den Speicher deines Webservers zumüllen.
Selbst unter 64-Bit ist dann durch Speicherfragmentierung irgendwann Schluss.

Ohne unhöflich sein zu wollen, aber da trennt sich wirklich die Spreu vom Weizen bzw. der Hobby-Programmierer vom Professional, der einfach schon zuviel (Schlimmes) gesehen hat und aus bitterer Erfahrung gelernt hat.

stahli 1. Okt 2020 09:01

AW: Schutzblöcke überflüssig!?
 
Ok, das ist ein gutes Beispiel und das kann ich auch nachvollziehen.

ABER: Dann muss allerdings auch eine Problembehandlung erfolgen und neben dem Freigeben der Objekte eine Fehlerbehandlung und Info an den Aufrufer erfolgen.

Dann passt das ja wieder.

Wenn aber nur die Objekte abgeräumt werden und der Aufrufer keinerlei Info erhält, dass etwas schief gelaufen ist, dann hat Paypal schnell ein echtes Problem.


Vielleicht habe ich die Beispiele, die man immer wieder sieht, wo also nur ein finally-Block ohne exception-Behandlung gezeigt wird, zu wörtlich genommen. Wenn damit immer auch eine Fehlerbehandlung verbunden wird, dann ist ja alles gut.

(Notfalls kann ich mal anhand eines kleines Demos und Videos den genaue Hintergrund meiner Frage noch besser verdeutlichen, wenn das jemand möchte.)

jaenicke 1. Okt 2020 09:07

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von stahli (Beitrag 1474667)
Eine bessere Robustheit erkenne ich durch einen finally-Block ohne wirkliche Fehlerbehandlung eben nicht. Aber das habe ich schon mehrfach erläutert.

Wer sagt denn, dass es keine Fehlerbehandlung gibt? Die kann und sollte ja in den Aufrufen der Funktionen passieren.

Oder ganz anders:
Durch einen Buffer Overflow wird Speicher überschrieben und deshalb knallt es an einer ganz banalen Stelle, an der du ansonsten nie eine Exception vermuten würdest.

So etwas lässt sich dann leider auch nicht immer so schnell lösen, vor allem wenn es sich nicht um eine einfach vorhersagbare Speicherstelle handelt (auf die man dann einen Datenhaltepunkt setzen kann). Was ist dann besser? Ein Programm, bei dem Exceptions soweit möglich behandelt sind und durch Ressourcenschutzblöcke keine Speicherlecks auftreten, so dass es bis zu einer Lösung weitgehend normal weiter läuft, oder ein Programm, das man dann quasi gleich stilllegen kann bis eine Lösung gefunden ist, weil aufgrund des Fehlers der Speicher voll läuft?

Deine Vorstellung bezüglich des Ausschließens von Fehlern hört sich irgendwie so an als würdest du ausschließlich von relativ überschaubaren Programmen reden, an denen nur eine Person arbeitet. Bei größeren Programmen funktioniert diese ideale Vorstellung aber nun einmal nicht. Außer es handelt sich im so etwas wie einen Autopiloten, bei dem aber auch sehr viel mehr Ressourcen in die Qualitätssicherung gesteckt werden als bei normalen Programmen (hoffentlich :lol:).

Oder anders:
Was wäre denn, wenn man bei dem Autopiloten deiner Logik folgen würde und sich darauf verlässt, dass keine unvorhersehbaren Fehler auftreten? Was, wenn dann doch ein Fehler passiert (siehe Tesla)? Soll man dann immer noch einfach sagen:
Zitat:

Zitat von stahli (Beitrag 1474650)
Bei einem unerwarteten Fehler arbeitet Dein Programm ohnehin nicht mehr sauber - das geht grundsätzlich nicht.

Dann schalten wir den Autopiloten einfach ab (weil es ja ohnehin nicht mehr sauber arbeitet) und das Auto, die Drohne oder die Marssonde knallen gegen das nächste Hindernis...

Unsere Anwendungen arbeiten auch nach unerwarteten Fehlern ggf. normal weiter. Es kommt nur darauf an wo ein Fehler auftritt. Das heißt nicht, dass solche Fehler dann nicht behoben werden müssen, aber man hat nicht direkt das Problem, dass vor Ort gar nichts mehr läuft.

Delphi.Narium 1. Okt 2020 09:25

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von stahli
Nach 1 Jahr tritt ein unerkannter Fehlerfall auf, der Kunde ruft an und beschwert sich über eine Fehlermeldung und fragt, ob seine Daten noch stimmen. Dann muss das Problem geklärt werden. Ob Person.Free noch durchlaufen wurde oder nicht, interessiert da nicht wirklich - nur welche Daten noch geändert und gespeichert wurden und wie sichergestellt werden kann, dass der Fehler nicht wieder auftritt.

Leider rufen aber nicht alle Kunden an oder erst, wenn sie durch wiederholen der zum Fehler führenden Funktion, quasi sichergestellt haben, dass da ein Fehler auftritt.

Und eine Beschwerde / Frage, ob de Daten noch sicher und in Ordnung sind, mag es ja geben, aber die Antwort muss immer sein: Ja die Daten sind sicher, die Daten sind in Ordnung. Wenn man da als Entwickler nicht sicher ist, dass man immer diese Antwort geben kann, hat man was falsch gemacht.

Ein Programm muss immer so geschrieben sein, dass auch bei einem schweren und unerwarteten Fehler, die Sicherheit der Daten garantiert ist. Auch dann noch, wenn der Anwender das Programm gegen alle Regeln der Vernunft weiter benutzt, neu startet und die zum Fehler führende Aktion wieder ausführt, das schlimmstenfalls mehrfach ...

Der größte Aufwand beim Programmieren ist nicht, richtigen und sauber funktionierenden Code zu schreiben und für eine korrekte Arbeit des Programmes zu sorgen, sondern sicherzustellen, dass bei allem davon abweichenden die Sicherheit und Korrektheit weiterhin garantiert ist.

Sprich: Die Fehlerbehandlung macht deutlich mehr Arbeit, als die eigentliche Progammlogik.

Und Schutzblöcke sind ein kleiner Teilbereich dessen.

@jaenicke
Jo, det isset.

Egal was in einem Programm an Fehlern passiert: Es läuft weiter und zwar ohne jegliche Einschränkung. Einen Fehler, der zu dem von stahli angesprochenen Szenario führt, dass es egal ist, ob man aufräumt oder nicht, darf es in Software für den professionellen Einsatz nicht geben Punkt. Und mindestens ein Dutzend Ausrufezeichen.

stahli 1. Okt 2020 09:37

AW: Schutzblöcke überflüssig!?
 
@jaenicke

Ja, meine Anwendungen sind recht überschaubar und ich arbeite allein daran.

Zitat:

Zitat von jaenicke (Beitrag 1474671)
Was ist dann besser? Ein Programm, bei dem Exceptions soweit möglich behandelt sind und durch Ressourcenschutzblöcke keine Speicherlecks auftreten, so dass es bis zu einer Lösung weitgehend normal weiter läuft, oder ein Programm, das man dann quasi gleich stilllegen kann bis eine Lösung gefunden ist, weil aufgrund des Fehlers der Speicher voll läuft?

Wenn durch den Fehler alle Konten der Bankkunden geleert wurden, wäre es besser, sofort abzubrechen und keine Daten mehr zu speichern. Wenn es sich um eine Zugriffsverletzung auf eine VCL-Komponente handelt, kann man erst mal problemlos weiter arbeiten.
Da es sich aber um völlig unerwartete Fehler handelt, für die man keine Behandlung vorgesehen hat, ist schwer zu sagen, was aktuell besser ist.


Mir ging es halt wirklich nur um solche Beispiele wie im Eingangspost, die man immer wieder überall findet.

Der Speicher läuft ja nicht gleich voll, wenn der Fehler einmal pro Monat aufläuft und das Programm ansonsten zuverlässig ohne Datenverlust funktioniert.
Dann kann man "in Ruhe" den Fehler bereinigen.

Wenn das Problem dagegen jede jede Minute auftritt (auch ohne Datenverlust) und nicht gleich gelöst werden kann und sonst den Speicher vollmüllt, dann kann man die Freigabe vielleicht in einen finally-Block setzten und die Fehlermeldung zunächst unterdrücken - bis man den Fehler vernünftig klären kann. Aber das wäre natürlich nur ein notfalls akzeptabler Workaround.

Solch einen ständig auftretenden Fehler würde man doch aber normalerweise schon in Tests finden und vermeiden, denke ich.


Ok, vielleicht sehe ich das zu optimistisch durch meine recht überschaubaren Projekte.


@Delphi.Narium

Dann können wir vielleicht zu dem Schluß kommen, dass das eingangs von mir besprochene Beispiel (das man immer wieder findet) tatsächlich nicht viel Wert hat, da dort keine Fehlerbehandlung erfolgt.

Mit Fehlerbehandlung ist das ja dagegen alles in Ordnung.

freimatz 1. Okt 2020 09:39

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von TiGü (Beitrag 1474595)
Einfach nur Nein!

Schutzblocke immer zu machen ist sinnvoll.

Delphi.Narium 1. Okt 2020 09:58

AW: Schutzblöcke überflüssig!?
 
Zitat:

Zitat von stahli (Beitrag 1474676)
Dann können wir vielleicht zu dem Schluß kommen, dass das eingangs von mir besprochene Beispiel (das man immer wieder findet) tatsächlich nicht viel Wert hat, da dort keine Fehlerbehandlung erfolgt.

Ja, solche Beispiel findet man immer.

Und man sollte sie als abschreckende Beispiele betrachten. Sie sind für den professionellen Einsatz sinnlos, kontraproduktiv, absolut ungeeignet.

Wenn ich mal was für mich programmiere oder nur 'ne schnelle Routine für 'ne einmalige Aufgabe, die nur ich nutze, spar' ich mir die Schutzblöcke auch. Aber das sind Routinen, die ich nur einmalig brauche, um was grundsätzlich auszuprobieren, einmalig 'ne Datei von Zustand A in den Zustand B zu bringen, ...

Aber wenn die Software von jemand anderem genutzt werden soll und das nicht nur einmalig, sondern dauerhaft im Geschäftsbetrieb, oder als dauerhaft nutzbares Hobbyprogramm, dann versuche ich das Programm so zu schreiben, dass es immer korrekt und sauber läuft, alles freigibt, immer verwertbare Fehlermeldungen ausgibt, und das auch noch in den Situationen, mit denen ich im Lebtag nicht gerechnet hätte, dass sie überhaupt möglich sein könnten. Selbst bei der Nutzung der Software vom größtmöglich denkbaren DAU, muss die Software noch sauber laufen. Und auch wenn im laufenden Betrieb Teile der Hardware abrauchen (Festplatte kaputt), verlustig gehen (Netzkabel gezogen, USB-Datenträger einfach mal eben so abgezogen), ..., muss bei professioneller Software die Datensicherheit garantiert werden können. (Hierunter fallen natürlich keine Datenverluste durch Hardwareschäden, aber die Daten auf 'nem vom Anwender einfach mal so abgezogenen USB-Datenträger, sollten konsistent bleiben.)


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:17 Uhr.
Seite 1 von 2  1 2      

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