Korrekturhinweise
Die in den Aufgaben beschriebenen Anforderungen müssen durch das Programm erfüllt sein, damit Bonuspunkte gesammelt werden können.
Dazu gehört auch, dass alle angeforderten Ressourcen beim erfolgreichen Beenden des Programms wieder freigegeben werden; im Fehlerfall müssen keine Ressourcen freigegeben werden.
Für jeden Fehler in der Implementierung werden Punkte von der maximal erreichbaren Punktzahl abgezogen.
Jede Datei (C-Datei oder Makefile) gilt als eigenes Modul.
Punkte werden in dem Modul abgezogen, wo laut Aufgabenstellung die Funktionalität zu erwarten ist.
Jedes Modul wird mit mindestens Null Punkten bewertet.
Die maximalen Punkte pro Modul stehen in der Aufgabenstellung.
Die folgenden Korrekturrichtlinien zeigen, wofür und in welchem Ausmaß Punkte bei Fehlern abgezogen werden.
Sie sind als Richtlinien zu verstehen und nicht vollständig.
In Ausnahmen kann davon abgewichen werden.
Falls nicht weiter spezifiziert, wird für jedes Auftreten eines Fehlers die genannten Punkte abgezogen, auch mehrfach für denselben Fehler an unterschiedlichen Stellen im Programm.
Tritt derselbe Fehler mehr als zweimal auf, so gibt es ab dem dritten Auftreten keinen Punktabzug mehr und er wird als Folgefehler gewertet.
Übersetzerfehler
Wenn sich ein Programm nicht übersetzen lässt werden vom jeweiligen Modul Punkte abgezogen.
Für jeden Auslöser von Übersetzerfehlern werden Punkte abgezogen.
Dies betrifft auch vom Übersetzer ausgelöste Warnungen, da mit -Werror
kompiliert wird.
Fehlerbild |
Punktabzug |
Auslösen eines Übersetzerfehlers |
>= 6 |
Falsche oder unzureichende Fehlerbehandlung
Nutzung von C-, Linux- und POSIX-Funktionen erfordern korrekte Fehlerbehandlung.
Mögliche Fehler sind in der man
-Page der betreffenden Funktion nachzulesen.
Alle Funktionen benötigen Fehlerbehandlung, außer die Funktion kann nicht fehlschlagen.
Ob eine Funktion fehlschlagen kann, richtet sich nach der Spezifikation (man funktion
).
Für jede falsche oder nicht ausreichende Fehlerbehandlung werden Punkte abgezogen.
Typische Bestandteile einer Fehlerbehandlung sind:
Nötige Fehlerbehandlung |
Punktabzug |
Label |
Prüfen auf Fehler |
1 |
|
errno wird zur Fehlerprüfung genutzt, wenn die Man-Page dies vorsieht |
1 |
|
Ausgabe des Fehlergrunds: mit perror(3) (Funktion setzt errno ); oder fprintf(3) (sonst); keine Fehlerausgabe bei selbst geschriebenen Bibliotheksfunktionen (z.B. der halde)! |
1 |
* |
Behandlung des Fehlers: exit(3) oder return ; kein exit bei selbst geschriebenen Bibliotheksfunktionen! |
1 |
** |
Insgesamt wird für eine normale Fehlerbehandlung (Ausnahmen siehe unten) maximal 2 Punkt abgezogen, dies gilt auch wenn die Fehlerbehandlung komplett fehlt.
Falls die Fehlerbehandlung das Programm beendet, müssen keine Ressourcen (angeforderter Speicher, offene Dateien, etc.) freigegeben werden.
Ausnahmen und Ergänzungen
Fehlerbild |
Anmerkung |
Punktabzug |
Fehlerbehandlung zu malloc(3) fehlt |
|
1 |
Fehlerausgabe auf stdout |
einmalig pro Abgabe |
1 |
Manche Funktionen benötigen aufwändigere Fehlerbehandlung, bei der das Prüfen auf einen Fehler komplizierter ist.
Somit kann mehr als ein Punkt abgezogen werden.
Der maximale Punktabzug pro Funktion ergibt sich aus der Summe der hier aufgezählten möglichen Fehler.
Dieser wird auch verwendet, wenn die Fehlerbehandlung komplett fehlt.
Nötige Fehlerbehandlung |
Punktabzug |
errno passend setzen sowie nach Aufruf prüfen |
1 |
endptr prüfen (Eingabe nicht leer und wurde vollständig gelesen) |
1 |
Ausgabe und Behandlung wie oben (*) und (**) |
2 |
Nötige Fehlerbehandlung |
Punktabzug |
Rückgabewert prüfen |
1 |
Mit feof(3) bzw. ferror(3) auf Fehler prüfen |
1 |
Ausgabe und Behandlung wie oben (*) und (**) |
2 |
Nötige Fehlerbehandlung |
Punktabzug |
Rückgabewerte EOF und 0xFF können unterschieden werden |
2 |
Prüfen des Rückgabewerts auf EOF |
1 |
Mit feof(3) bzw. ferror(3) auf Fehler prüfen |
1 |
Ausgabe und Behandlung wie oben (*) und (**) |
2 |
Nötige Fehlerbehandlung |
Punktabzug |
Rückgabewert prüfen |
1 |
Falls die angeforderte Information ein (Min-/Max-)Limit ist, passend errno setzen und prüfen |
1 |
Ausgabe und Behandlung wie oben (*) und (**) |
2 |
Nötige Fehlerbehandlung |
Punktabzug |
Rückgabewert prüfen |
1 |
errno passend vor jedem Aufruf setzen sowie nach Aufruf im Fehlerfall prüfen |
1 |
Ausgabe und Behandlung wie oben (*) und (**) |
2 |
Nötige Fehlerbehandlung |
Punktabzug |
Rückgabewert prüfen |
1 |
errno im Fehlerfall prüfen |
1 |
Falls errno gleich ERANGE , ohne Abbruch Fehlergrund beseitigen und erneut aufrufen |
2 |
Ausgabe und Behandlung wie oben (*) und (**) |
2 |
Nötige Fehlerbehandlung |
Punktabzug |
Rückgabewert prüfen |
1 |
Ausgabe des Fehlergrunds mit perror(3) (bei Rückgabe von EAI_SYSTEM ) oder gai_strerror(3) (sonst) |
2 |
Behandlung bei Fehler wie oben (**) |
1 |
Fehlerbehandlung bei Ein-/Ausgabe
Ein-/Ausgabe benötigt Fehlerbehandlung um beispielsweise Fehler beim Schreiben auf eine volle Festplatte zu erkennen und damit Datenverlust zu verhindern.
Fehlerbehandlung ist für alle Funktionen nötig, die Ein-/Ausgabe durchführen die zur Grundfunktionalität des Programms gehören (geht aus der Aufgabe hervor).
Das beinhaltet beispielsweise printf(3)
, fclose(3)
oder close(2)
.
Ausgenommen davon sind dabei die Fehlermeldungen selbst sowie unwichtige Ausgaben.
Falls sich das Programm bei einem Schreibfehler sowieso mit einem Fehlercode beenden würde (bspw. SIGPIPE
) so ist keine Fehlerbehandlung nötig.
Damit auch Schreibfehler auf stdout
erkannt werden (wichtig falls in eine Datei umgeleitet wird), muss vor Beendigung des Programms stdout
mit fflush(3)
geflushed werden.
Dies ist nur nötig, falls das Programm Ausgaben auf stdout
nutzt.
Verbotene Funktionen
Folgende Funktionen ermöglichen keine korrekte Fehlerbehandlung und dürfen nicht verwendet werden.
Als Punktabzug ergibt sich jeweils der maximale Punktabzug der korrekten Alternative.
Verbotene Funktion |
Alternative |
Punktabzug |
atoi(3) |
strtol(3) |
siehe oben bei strtol(3) |
Programmierfehler
Fehlerbild |
Punktabzug |
static fehlt |
1 |
Unnötige globale Variable |
1 |
free(3) fehlt |
2 |
close(2) oder fclose(3) fehlt |
2 |
printf(variable) , kein Format-String und variable vom Nutzer |
2 |
zu kleiner Puffer |
2 |
Verlust von benötigter Information durch Casten von Datentypen |
2 |
falsche Funktionsparameter |
1 |
falsche Funktionssignatur |
4 |
errno wird vor perror(3) überschrieben (z.B. durch Funktionsaufruf) |
1 |
DoS durch getline() möglich |
4 |
sonstige Programmierfehler (Folgefehler nur für dieselben Programmierfehler) |
2 |
Programmierstil (Fehler)
Fehlerbild |
Punktabzug |
Unnötig (deutlich zu) große Puffer |
1 |
goto , falls offensichtlich unnötig oder um Schleifen nachzubauen (Sprung nach oben) |
2 |
Ausgabe in Bibliotheksfunktionen (z.B. bei der halde) |
1 |
exit(3) in Bibliotheksfunktionen (z.B. bei der halde); abort(3) ist erlaubt, wenn es die Angabe vorsieht |
2 |
unnötiges Verwenden von Makros (pro Makro) |
1 |
offensichtlich schlechter Code (von Folgefehlern ausgenommen) |
2 |
Programmierstil (Hinweise)
Muster |
Verbesserte Lösung |
if (var) { free(var); } |
free(var); /* NOOP, iff var == NULL */ |
if (ptr == 0) { ... } |
if (ptr == NULL) { ... } |
(*ptr).member |
ptr->member |