2009-06-04 8 views
2

Ich habe über die Schwierigkeit zu denken entstand mit C Fehlerbehandlung .. wie die tatsächlich tutMit Callback-Funktionen zur Fehlerbehandlung in C

if(printf("hello world")==-1){exit(1);} 

Aber Sie brechen gemeinsame Standards nicht so weitschweifig zu tun, und in der Regel nutzlos Codierung. Was wäre, wenn Sie einen Wrapper um die libc hätten? wie so dass Sie etwas tun könnte, wie ..

//main... 
error_catchall(my_errors); 
printf("hello world"); //this will automatically call my_errors on an error of printf 
ignore=1; //this makes it so the function will return like normal and we can check error values ourself 
if(fopen.... //we want to know if the file opened or not and handle it ourself. 
} 

int my_errors(){ 
    if(ignore==0){ 
     _exit(1); //exit if we aren't handling this error by flagging ignore 
    } 
return 0; 
//this is called when there is an error anywhere in the libc 
} 
... 

ich angesichts mache einen solchen Wrapper wie ich meine eigenen BSD lizenziert libc bin Synthese (so habe ich bereits die unantastbar berühren ..), aber ich möchte wissen, was die Leute darüber denken. würde dies tatsächlich im wirklichen Leben funktionieren und nützlicher sein als die Rückkehr von -1?

+0

Die Überprüfung auf printf (...) == -1 ist nicht sinnvoll, da printf (...) die Anzahl der gedruckten Zeichen zurückgibt und nicht kleiner als 0 sein kann. – Kai

+1

"Die Anzahl der gedruckten Zeichen wird zurückgegeben Wenn ein Fehler aufgetreten ist, wird -1 zurückgegeben. " – Earlz

+0

Sie meinen, dass alle libc-Funktionen umgebrochen sind, um im Fehlerfall zu den Parametern von error_catchall zu gelangen? – LB40

Antwort

1

Aber wie könnten Sie den Fehler abfangen, wenn er erwartet wurde? Zum Beispiel könnte ich erwarten, dass eine geöffnete Datei fehlschlägt und mit Code statt mit dem generischen Fehler-Catcher umgehen möchte.

Dazu benötigen Sie zwei Versionen jeder Funktion. Einer, der Fehler gefangen hat, und der andere Fehler.

Ich habe so etwas vor langer Zeit ohne Änderung der Bibliothek gemacht. Ich habe gerade Wrapper-Funktionen für allgemeine Aufrufe erstellt, die eine Fehlerprüfung durchgeführt haben. So hat mein Aufruf von errchk_malloc die Rückgabe überprüft und einen Fehler ausgegeben, wenn die Zuweisung fehlgeschlagen ist. Dann habe ich diese Version überall anstelle des eingebauten malloc verwendet.

2

während dieser Jahre habe ich mehrere Versuche, ahmt gesehen habe try/catch in ANSI C:

Ich denke, dass try/catch-Ansatz ist einfacher als Ihre.

+2

Anstatt solche Frameworks zu verwenden, ist es auch möglich, einfach nur goto zu verwenden. Hier ein Beispiel: #define TRY/* nichts */ #define CATCH (Label) Label: #define throw (Label) goto Label try { fd = open (...); if (fd <0) THROW (open_failed); ... } Rückkehr; CATCH (open_failed) { ... } Dies skaliert nicht und ich würde solche Makros nicht wirklich empfehlen, aber der Punkt ist, dass es möglich ist, goto für die Fehlerbehandlung so zu verwenden, wie Sie Ausnahmen verwenden , obwohl goto auf eine einzige Funktion beschränkt ist, so dass Sie sie nicht an die aufrufende Funktion weitergeben können. – hlovdal

+2

Ihr Kommentar kann betitelt werden "goto als nützlich angesehen werden" :) – dfa

+2

Ja;) Meiner Meinung nach ist Goto zu wenig genutzt, und ich empfehle oft Menschen, es für die Fehlerbehandlung zu verwenden. – hlovdal

0

wenn das Ziel sauber so schnell zu verlassen ist wie ein Fehler auftreten, das ist ok ... aber wenn Sie ein Minimum an Fehlerbehebungs tun wollen, kann ich nicht sehen, wie Ihr Ansatz nützlich ist ...

um diese Art von Problem zu vermeiden, habe ich manchmal LD_PRELOAD_PATH verwenden, um mein Fehlermanagement zu integrieren (nur für meine eigenen Projekte, da dies keine wirklich gute Praxis ...)

0

Haben Sie wirklich den Standard ändern mögen Verhalten Ihres LIBC? Sie könnten ein paar Erweiterungen um allgemeine Funktionen hinzufügen.

Zum Beispiel verwendet Gnome g_malloc und g_try_malloc. Ersteres wird bei einem Fehler abgebrochen, während das spätere einen Null-Zeiger wie malloc ergibt.