blob: 264414ae2d46d8ff0fe51bc3798db38ac2a528b1 [file] [log] [blame]
Zesstrae28b34f2021-08-21 23:04:07 +02001NAME
2 assert
3
4SYNTAX
5 assert (expr, msg)
6
7DESCRIPTION
8
9 Wenn man ein Programm schreibt, ist es oft eine gute Idee, an
10 wichtigen Stellen Pruefungen auf grundlegende Annahmen (oder
11 "unmoegliche" Fehlerzustaende) zu formulieren.
12
13 Beispiele hierfuer koennten Pruefungen darauf sein, ob an eine
14 Funktion die richtigen Daten uebergeben wurden oder aus einer Property
15 die richtige Datenstruktur ausgelesen wurde oder ob eine Annahme
16 stimmt, von der die Magierin ausgeht und die wichtig ist fuer den
17 weiteren Ablauf.
18
19 Das 'assert'-Makro ist eine bequeme Moeglichkeit, solche Pruefungen
20 zu formulieren, welche an dieser Stelle einen Laufzeitfehler
21 ausloesen, falls <expr> unwahr sein sollte. Oder anders: es dient
Zesstrac5781082021-09-07 21:36:50 +020022 dazu, die Annahme der Magierin zu pruefen, dass <expr> in diesem
Zesstrae28b34f2021-08-21 23:04:07 +020023 Moment != 0 ist.
24 In der Fehlermeldung wird in diesem Fall die aktuelle Datei, Zeile,
Zesstrac5781082021-09-07 21:36:50 +020025 ggf. Funktion und die vom Magier formulierte <msg> ausgegeben.
26 Sollte einem nichts sinnvolles einfallen, schreibt einfach man einen
Zesstrae28b34f2021-08-21 23:04:07 +020027 String mit der <expr> rein.
28
29 Hierbei sollte man aber bedenken, ob es an dieser Stelle gut ist, die
30 Programmausfuehrung hart abzubrechen oder es notwendig sein koennte,
31 zunaechst "aufzuraeumen", um inkonsistente Zustaende spaeter zu
32 vermeiden. assert() sollte nur verwendet werden, wenn der Abbruch der
33 Programmausfuehrung an dieser Stelle eine *sinnvolle* Reaktion auf den
34 Fehlerzustand ist.
35 Es ist moeglich, dass assert() in ein catch(...;publish) zu
36 formulieren, um eine Fehlermeldung zu produzieren, aber die
37 Ausfuehrung fortzusetzen. Aber auch bitte ueberlegen, ob das sinnvoll
38 ist.
39
40 Das Makro ist in dem Systemheader <assert.h> definiert, welche also
41 zuvor inkludiert werden muss.
42
43 Es ist moeglich, in einem File alle assert() auf einmal abzuschalten,
44 indem vor dem Inkludieren von <assert.h> das Define NDEBUG definiert
45 wird (egalf auf welchen Wert). Das hat den Vorteil, dass man sie
46 spaeter (z.B. zum Debuggen) schnell wieder einschalten kann.
47
48 Der Ausdruck <expr> sollte *keinerlei* Seiteneffekte haben. Dies ist
49 speziell wichtig, wenn NDEBUG spaeter gesetzt wird, weil in dem Fall
50 auch der Seiteneffekt nicht mehr stattfindet: <expr> wird dann gar
51 nicht mehr ausgewertet. Beispielsweise ist assert (++i > 0); oder
52 assert (data = QueryProp(FOO)); eine sehr schlechte Idee.
53 Ohnehin waeren Ausdruecke mit Seiteneffekt sehr schlechter Stil.
54
55
56EXAMPLE
57
58 // Pruefung auf Vorraussetzungen einer Funktion
59 // Eine Funktion zum Bezahlen von Geld verlaesst sich darauf, dass sie
60 // nur mit positiven Werten gerufen wird. Wenn jemand sie mit
61 // negativen Werten ruft, kommt Unsinn dabei raus.
62 void pay(int money) {
63 assert(money > 0, "Negativen Betrag erhalten");
64 ...
65 // Bemerkung: man sollte keine Benutzereingaben mit assert() pruefen!
66
67 // Eine Funktion darf nur in leeren Raeumen gerufen werden und geht
68 // auch davon aus, dass der Raum leer ist:
69 int dispose_me() {
70 assert(!sizeof(all_inventory()); "Raum nicht leer!");
71 remove(1);
72 }
73
74SEE ALSO
75 raise_error(E), throw(E)
76