Die Fehlerbehandlung in der Programmiersprache C war schon immer eine Aufgabe des Entwicklers. In der Standardbibliothek gibt es keine Ausnahmen, Fehler werden durch Rückgabewerte oder die globale Variable errno zurückgegeben (Beginn der Verwendung - UNIX der 1970er Jahre, danach POSIX und ANSI C). Solche Mechanismen werden auch heute noch verwendet, um den Ablauf bei Ausnahmesituationen zu steuern.
Fehler bei der Arbeit mit Standardfunktionen (Dateioperationen, Speicherzuweisung, String-Funktionen) können ohne besondere Kontrolle unbemerkt bleiben. Falsche Verarbeitung - Ignorieren des Rückgabewerts, falsche Interpretation von errno, fehlende Aufräumarbeiten - führt zu falschem Verhalten des Programms, Abstürzen und Schwachstellen.
Eine korrekte Fehlerbehandlung erfordert eine verpflichtende Analyse der von Funktionen zurückgegebenen Werte, die Verwendung von errno nur direkt nach einem Fehler und eine informative Fehlerausgabe. Rückgabewerte sind für interne Funktionen vorzuziehen - sie ermöglichen die Verarbeitung ohne globale Nebeneffekte. errno wird häufiger bei Systemaufrufen und Funktionen der Standardbibliothek angewendet. Nach jeder potenziell gefährlichen Operation wird die Rückgabe analysiert, und der globale Zustand (errno) sollte nicht durch Zwischenausführungen überschrieben werden.
Beispielcode:
#include <stdio.h> #include <errno.h> #include <string.h> FILE *open_file(const char *filename) { errno = 0; FILE *f = fopen(filename, "r"); if (!f) { fprintf(stderr, "Fehler: %s ", strerror(errno)); } return f; }
Wichtige Merkmale:
Kann man errno für Benutzerfunktionen verwenden, wenn man Fehler nach oben weitergeben möchte?
Nein, errno ist nur für Standardbibliotheks- und Systemaufrufe gedacht. Sie ist global, kann an jeder Stelle überschrieben werden und ist nicht für eigene Funktionen geeignet.
Muss man errno vor jedem Funktionsaufruf setzen?
Nein, es wird jedoch empfohlen, errno (zum Beispiel auf null) vor Aufrufen zurückzusetzen, wenn eine Analyse der Änderungen geplant ist. Nicht jede Funktion ändert errno bei Erfolg, sondern nur bei Fehler.
errno = 0; ... gefährlichen Funktionsaufruf ...
Kann man errno nach jeder Funktion vertrauen?
Nur für die Funktionen, die laut Standard ausdrücklich errno bei einem Misserfolg setzen. Viele Funktionen der Standardbibliothek berühren errno bei Erfolg nicht. Die Dokumentation ist Ihr Freund.
Öffnen einer Datei ohne Überprüfung des Ergebnisses, Fehler werden nicht analysiert, das Programm funktioniert falsch, wenn die Datei nicht vorhanden ist:
Vorteile:
Nachteile:
Nach jeder kritischen Funktion wird das Ergebnis überprüft, im Fehlerfall wird eine detaillierte Nachricht mit strerror(errno) ausgegeben, die Ausführung wird korrekt beendet:
Vorteile:
Nachteile: