8.4 Programmdiagnose mit assert()
Die Definition des Makros assert() (und auch von static_assert; siehe Abschnitt 3.9.4, »Sicherheit beim Kompilieren mit static_assert«) in der Header-Datei assert.h hängt von dem Makro NDEBUG ab, das nicht von assert.h definiert wird. Wenn Sie NDEBUG definieren, werden alle im Code folgenden assert()-Makros vom Compiler ignoriert. Wichtig ist es dabei auch, dass Sie NDEBUG vor dem Inkludieren von assert() definieren. Definieren Sie NDEBUG nicht, können Sie das Makro assert() verwenden, um Ausdrücke zur Laufzeit auf logische Fehler zu testen. Ist der Ausdruck gleich 0, wird eine Fehlermeldung als Diagnose ausgegeben und das Programm mit abort() abgebrochen. Gerade wenn Sie anfangen, ein Programm zu entwickeln und zu testen, sind solche Assertions (dt. Zusicherungen) sehr hilfreich.
Listing 8.7 demonstriert das assert()-Makro in der Praxis:
00 // Kapitel8/assert.c
01 #include <stdio.h>
02 #include <stdlib.h>
03 #include <math.h>
04 // #define NDEBUG
05 #include <assert.h>
06 int main(void) {
07 double x = 0.0;
08 printf("Bitte eine positive Gleitkommazahl: ");
09 if( scanf("%lf", &x) != 1 ) {
10 printf("Fehler bei der Eingabe ...\n");
11 return EXIT_FAILURE;
12 }
13 assert(x >= 0.0);
14 double dval = sqrt(x);
15 printf("%lf\n", dval);
16 return EXIT_SUCCESS;
17 }
Listing 8.7 »assert.c« zeigt, wie Sie mit »assert()« Ihre Programme auf fehlerhaftes Verhalten prüfen können.
In diesem Beispiel wird in Zeile (13) überprüft, ob die Gleitkommazahl größer bzw. gleich 0.0 ist. Solange dieser Gesamtausdruck nicht ungleich 0 ist, wird das Programm ordnungsgemäß ausgeführt. Das Programm gibt bei der Ausführung z. B. Folgendes aus:
Bitte eine positive Gleitkommazahl: 3.1
1.760682
Bitte eine positive Gleitkommazahl: -3.3
Assertion failed: file /Projects/listing007/
listing007.c, func main, line 15, x >= 0.0
abort -- terminating
*** Process returned 1 ***
Hier sehen Sie das Programm bei der Ausführung, wobei das auskommentierte NDEBUG in der Zeile (04) definiert wurde:
Bitte eine positive Gleitkommazahl: -3.3
nan
[»] assert() für die Entwicklungsphase
Der Einsatz von assert() sollte der Entwicklungsphase vorbehalten sein. Ein Anwender kann in der Regel nicht viel mit der Fehlerausgabe anfangen. Wenn Sie das Programm freigeben, sollten Sie für das Release NDEBUG definieren, wodurch jedes assert() im Programm durch ein Null-Makro ersetzt wird. Erwägen Sie auch, die Funktion static_assert() zu verwenden, mit der Sie eine Überprüfung bereits während der Kompilierzeit vornehmen können. static_assert() ist seit C11 dabei und wurde bereits in Abschnitt 3.9.4, »Sicherheit beim Kompilieren mit static_assert«, behandelt.