Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Welchen Sinn hat diese Assert Zeile? (https://www.delphipraxis.net/178362-welchen-sinn-hat-diese-assert-zeile.html)

Popov 3. Jan 2014 19:18

Welchen Sinn hat diese Assert Zeile?
 
Ich sehe gelegentlich im Internet in fremden Prozeduren gleich am Anfang eine Assert Zeile. Das sieht in etwa so aus wie hier im Beispiel:
Delphi-Quellcode:
procedure Beispiel(Font: TFont);
begin
  Assert(Assigned(Font));
  ...
Was Assert macht ist mir klar, auch was Assigned macht. Somit ist mir durchaus klar was die Zeile bewirkt, bzw. bewirken könnte. Ist das Objekt hier nil, gibt es eine Fehlermeldung.

Was ich aber nicht erkenne ist der Sinn dahinter. Ich kenne etwa eine halbe Million Prozeduren in denen Objekte per Parameter übergeben werden und sie kommen ohne diese Zeile aus. Es kann schon mal vorkommen, dass ein Objekt nil ist. Dann gibt es eine Fehlermeldung (auch ohne Assert), dann sucht man den Fehler, korrigiert ihn und gut ist es.

Erzählt mir einer, dass das nützlich in der Entwicklung ist, weil man dann eine eigene Fehlermeldung bekommt, dann stimme ich dem zu. Wie gesagt, während der Entwicklung. Dann aber raus.

Denn ich erkenne nicht den Sinn der Zeile im funktionierendem Programm. Entweder ist das Objekt nil, dann erkennt man das vermutlich schon in der Entwicklung, oder nicht, dann stellt sich die Frage wieso die Zeile in einer funktionierenden Prozeduren steht.

Aber vielleicht erkenne ich nur den tieferen Sinn nicht.

Aphton 3. Jan 2014 19:34

AW: Welchen Sinn hat diese Assert Zeile?
 
Ich glaube dass es sich hier um eine (unnötige) Optimierung handelt: Asserts werden, wenn ausgeschaltet und soweit ich mich richtig erinnere, gar nicht erst reinkompiliert!

Wenn man also nicht im Debugmodus mit Asserts arbeitet sondern im Release, dann fällt genau die eine Zeile weg.

Kann sein, dass ich falsch liege; aber sonst ergäbe es wirklich keinen SInn!

jaenicke 3. Jan 2014 19:38

AW: Welchen Sinn hat diese Assert Zeile?
 
Assertions sind dafür gedacht, dass man bei der Entwicklung bestimmte problematische Werte abfangen kann, ohne dass diese Prüfungen im fertigen Programm anschlagen. Denn für ein Release kompiliert man normalerweise ohne aktivierte Assertions. Das ist in den Projektoptionen auf der Seite Compilieren und somit ohne weitere Anpassungen im Quelltext einstellbar.

Und man erhält bei einem Assert auch die Position im Quelltext, an der das Problem aufgetreten ist, ohne dafür Stacktraces usw. bemühen zu müssen.

Meflin 3. Jan 2014 19:39

AW: Welchen Sinn hat diese Assert Zeile?
 
Zitat:

Zitat von Aphton (Beitrag 1241989)
Kann sein, dass ich falsch liege; aber sonst ergäbe es wirklich keinen SInn!

Doch, nennt sich selbstdokumentierender Code - so sehe ich auf den ersten Blick, ob ich als Caller diesen Fall nun selber abfangen muss, oder nicht.

Abgesehen davon kann man mit solchen Asserts nicht erlaubte Zustände nahe an der potentiellen Fehlerquelle abfangen - der auftretende Defekt ist ja in der Praxis sehr oft an einer völlig anderen Stelle zu beobachten, und dann spart man sich durch solche Asserts viel Zeit und Nerven.

Sir Rufo 3. Jan 2014 19:57

AW: Welchen Sinn hat diese Assert Zeile?
 
Korrekterweise müsste diese Zeile so im Code stehen
Delphi-Quellcode:
{$IFDEF DEBUG}
Assert( ... );
{$ENDIF}
damit diese korrekterweise nicht in den Produktivcode fließt.

Da man diese Zeilen aber in Code von Anderen für Andere findet, werden diese Zeilen dort mit eingewoben um unbedarften Programmierern so früh wie möglich die Fehler bei der Benutzung des Codes um die Ohren zu hauen.
(gerade falls der Fehler erst später in den Standard-Units zum Tragen kommt, dann heißt es öfter mal "dein Code tut nicht")

Somit ist diese Zeile nur dafür da RTFM-Rückfragen zu minimieren ;)

Der schöne Günther 3. Jan 2014 20:12

AW: Welchen Sinn hat diese Assert Zeile?
 
Ohne mich damit richtig auseinandergesetzt zu haben, konnte ich mich damit nie anfreuden. Ich dokumentiere es und werfe eine
Delphi-Quellcode:
EArgumentNilException
wenn jemand doch eine leere Referenz reinsteckt. Läuft doch im Endeffekt aufs Gleiche raus, oder?

jaenicke 3. Jan 2014 20:18

AW: Welchen Sinn hat diese Assert Zeile?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1241996)
Korrekterweise müsste diese Zeile so im Code stehen
Delphi-Quellcode:
{$IFDEF DEBUG}
Assert( ... );
{$ENDIF}
damit diese korrekterweise nicht in den Produktivcode fließt.

Nein, gerade nicht...
Wenn du Assertions in den Projektoptionen deaktivierst, wird an der Stelle kein entsprechender Code erzeugt. Das ist daher genau nicht notwendig. Genau deshalb ist es sinnvoll Assertions statt sonstigem Code beim Entwickeln zu nutzen.

Sir Rufo 3. Jan 2014 20:19

AW: Welchen Sinn hat diese Assert Zeile?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1241999)
Ohne mich damit richtig auseinandergesetzt zu haben, konnte ich mich damit nie anfreuden. Ich dokumentiere es und werfe eine
Delphi-Quellcode:
EArgumentNilException
wenn jemand doch eine leere Referenz reinsteckt. Läuft doch im Endeffekt aufs Gleiche raus, oder?

Ja, allerdings ist das auch nur für den Entwickler, denn der hat einen Fehler bei der Programmierung gemacht und dann ist das Assert besser/gleichwertig/einfacher, weil dort auch die Zeilennummer mitkommt ;)

Andere Exceptions (z.B. Socketfehler) können teilweise auch vom Anwender behoben werden (Netzwerkkabel einstecken, Server einschalten, Internetverbindung prüfen, ...) und sind nicht zwangsweise Programmierfehler sondern können auch Kontext-Fehler sein

Zitat:

Zitat von jaenicke (Beitrag 1242000)
Zitat:

Zitat von Sir Rufo (Beitrag 1241996)
Korrekterweise müsste diese Zeile so im Code stehen
Delphi-Quellcode:
{$IFDEF DEBUG}
Assert( ... );
{$ENDIF}
damit diese korrekterweise nicht in den Produktivcode fließt.

Nein, gerade nicht...
Wenn du Assertions in den Projektoptionen deaktivierst, wird an der Stelle kein entsprechender Code erzeugt. Das ist daher genau nicht notwendig. Genau deshalb ist es sinnvoll Assertions statt sonstigem Code beim Entwickeln zu nutzen.

Ok, übergeredet :)

Furtbichler 3. Jan 2014 22:21

AW: Welchen Sinn hat diese Assert Zeile?
 
Nennt sich übrigens 'fail fast'. Genauergesagt sind das ca. 5% von Fail fast und noch genauer ist das nur dann fail fast, wenn die Assertions mit kompiliert werden.
Das fail fast Paradigma sorgt dafür, das ein System zum frühestmöglichen Zeitpunkt meckert. Ohne das Assert/If würde die Klasse mit Sicherhiet auch irgendwo knallen, aber erst später.

Zu fail fast gehört u.a. auch, das ein Iterator (for in) meckert, wenn versucht wird, die Enumeration (aka die Liste) zu verändern, während man durch sie durch iteriert. Ich glaube, Delphi ist hier noch nicht so weit.

Ich musste mich auch daran gewöhnen. Macht den Code ein wenig unleserlicher, finde ich, aber wenn man es kennt, ist es wirklich ein Teil der Spezifikation/Dokumentation. In C# kann man das mit Attributen (Annotations) machen. Irgendwo gabs vor kurzem hier einen interessanten Thread darüber.

Namenloser 3. Jan 2014 22:41

AW: Welchen Sinn hat diese Assert Zeile?
 
Assertions kann man wie so eine Art Pre- oder Post-Condition verwenden. Ich habe das z.B. letztens exzessiv eingesetzt, als ich (a,b)-Bäume implementiert habe. Und da ist es durchaus sinnvoll, wenn der Assert-Code nicht in der Release-Fassung landet, weil einige der Prüfungen, ob der Baum gültig ist, recht kompliziert sind, sodass die Laufzeitgarantien mit dem Assertion-Code nicht eingehalten werden würden.

Exceptions sollte man an Stellen einsetzen, wo der Fehler durch falsche Benutzung wirklich ausgelöst werden könnte. Assertions kann man dagegen in Fällen einsetzen, die theoretisch gar nicht auftreten sollten.

Z.B. beim (a,b)-Baum sollte es ja theoretisch nie passieren, dass Invarianten des Baumes kaputt gehen, egal was der Benutzer damit anstellt. Aber bei der Entwicklung macht man immer erst mal was falsch und da hilft sowas beim Debuggen enorm. Wenn man Ende dann alles läuft, könnte man den Assertion-Code natürlich prinzipiell wieder rauslöschen, aber wenn man ihn schon mal hat, ist es doch besser, ihn gleich drinzulassen, denn das hilft ja auch dem menschlichen Leser.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:38 Uhr.
Seite 1 von 2  1 2      

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