Ich arbeite an etwas Code, der viel
erzeugt %Vor% Warnungen, wenn mit g ++ kompiliert, und ich frage mich über das beste Programmiermuster, um tatsächlich den Rückgabewert einer großen Anzahl von separaten sequentiellen fwrite
s aufzuzeichnen und zu behandeln (dh nicht die gleiche fwrite
in einer Schleife)
Sagen wir, dass der Code im Moment so aussieht:
%Vor%Ich denke gerade über etwas wie das nach, aber ich habe möglicherweise Schwierigkeiten, den Dateizeiger aufzuräumen:
%Vor%Ich denke, dass dieser Ansatz eindeutig besser ist als Nesting, was zu schnell zu verrückt werden würde:
%Vor%Sicherlich gibt es bereits ein bewährtes Best-Practice-Muster für diese Art von Dingen, obwohl?
Natürlich, da ich mich hauptsächlich damit beschäftige, die Compiler-Warnungen loszuwerden, könnte ich einfach den Rückgabewert einer Dummy-Variablen zuweisen und sie ignorieren, aber ich möchte es zuerst richtig versuchen.
%Vor%Update: Ich habe das C ++ - Tag entfernt, da dieser Code wirklich nur mit g ++ kompiliert wird. Daher werden c-basierte Lösungen benötigt, um mit dem Rest der Codebasis zu bleiben.
>Ich würde etwas in dieser Richtung tun:
%Vor%Mit ein wenig C99 Makro Magie
%Vor% und mit ferror()
anstelle unserer eigenen Fehlerflagge, wie von Jonathan Leffler vorgeschlagen, kann dies als
Wenn neben io-Fehlern noch andere Fehlerbedingungen vorliegen, müssen Sie sie dennoch mit einer oder mehreren Fehlervariablen verfolgen.
Auch Ihre Überprüfung gegen sizeof(blah)
ist falsch: fwrite()
gibt die Anzahl der geschriebenen Objekte zurück!
Die C-Ausnahmebehandlung des armen Mannes basiert auf goto (tatsächlich ist die einzige und einzige Instanz, die NICHT schädlich ist):
%Vor%Sie bekommen die Idee. Umstrukturieren Sie wie gewünscht (Einzel- / Mehrfachrückgaben, einzelne Bereinigung, benutzerdefinierte Fehlermeldungen usw.). Aus meiner Erfahrung ist dies das am häufigsten verwendete C-Fehlerbehandlungsmuster. Der entscheidende Punkt ist: NIEMALS STDLIB-Returncodes ignorieren, und ein guter Grund dafür (z. B. Lesbarkeit) ist nicht gut genug.
Sie könnten eine Wrapper-Funktion schreiben
%Vor%und ersetzen Sie dann alle Aufrufe von fwrite durch new_fwrite
Das Ignorieren von Fehlern ist eine schlechte Idee. Es ist viel besser, etwas Fieses zu tun, wie das Programm zum Absturz zu bringen, so dass zumindest etwas schief läuft, anstatt still zu verfahren. Noch besser ist die Überprüfung und Wiederherstellung von Fehlern.
Wenn Sie C ++ verwenden, können Sie einen RAII-Wrapper für die Datei * erstellen, damit er immer geschlossen wird. Sehen Sie sich std :: auto_ptr für Ideen an. Sie können dann jederzeit einen nützlichen Fehlercode oder von der Funktion zurückgeben oder eine Ausnahme auslösen und sich keine Gedanken über vergessene Aufräumobjekte machen.
Sie können die Warnungen wie folgt entfernen:
%Vor%Wenn Sie Ihre Hauptfrage ansprechen, wenn einer der fwrite () -Aufrufe fehlschlägt, würde ich annehmen, dass es keinen Sinn ergibt, fortzufahren, da die Ausgabe vermutlich beschädigt ist. In diesem Fall und wenn Sie C ++ getaggt haben, würde ich eine Ausnahme auslösen.
Vielleicht so etwas? Sie fangen die Fehler ab, ohne den Code zu unlesbar zu machen, und Sie können nach dem Ende der falschen Schleife bereinigen.
%Vor%So etwas würde funktionieren
%Vor%Wenn Sie besorgt sind, dass Zeiger bereinigt werden, können Sie den Zeiger in eine Art Smart-Zeiger einbinden, bevor Sie Ihre fwrite's ausführen.
Wenn Sie keine intelligenten Zeiger verwenden wollen, funktioniert das zwar, aber es ist unordentlich, also würde ich zuerst die intelligente Zeigerroute ausprobieren
%Vor%Eine potentiell elegante C-Lösung dafür könnte in etwa so aussehen (Warnung - ungetesteter, nicht kompilierter Code):
%Vor%Das obige erreicht zwei Ziele gleichzeitig:
Leider sind die 'hässlichen' if (ok)
Bausteine notwendig, wenn Sie die Kurzschlussauswertung nicht überall verwenden wollen. Ich habe gesehen, dass dieses Muster in vergleichsweise kleinen Funktionen verwendet wird, wobei überall eine Kurzschlussbewertung verwendet wird, und ich würde denken, dass es wahrscheinlich am besten für diese spezielle Verwendung geeignet ist.
Ok, da ich nach einer c
Lösung suche (keine Ausnahmen), wie wäre es mit:
Und dann in meinem Code habe ich:
%Vor%