Wie viel prüft ihr gültige Werte in Funktionen?



  • SeppJ schrieb:

    Prüfen auf Logikfehler zur Laufzeit? Nein, nie. Wozu programmiere ich denn in C++, bloß um dann die Kindersicherung einzuschalten? Dann habe ich die falsche Sprache für das Projekt gewählt.

    Benutzereingaben werden vor der Verarbeitung genauestens geprüft, aber nicht die Tatsache, ob der Programmierer in der Lage ist, ein korrektes Programm zu schreiben.

    Für viele Programme, die in C++ geschrieben werden ist das ein berechtigter Einwand, es gibt allerdings auch Einsatzgebiete,
    die eine besonders hohe Programmstabilität erfordern und wo man selbst bei einem programmierfehler nicht kommentarlos aussteigen sollte:
    z.B. für medizinische Geräte, besonders wenn diese Patienten überwachen oder Ärzte bei Eigngriffen unterstützen, Steuersoftware für technische Anlagen
    oder Fahrzeuge jeglicher Art (Flugzeuge, Autos, oder ... Ariane 5 anyone? ;))

    Diese Programme sollten wohl zumindest würdevoll mit so etwas wie einem "Not-Aus" beendet werden,
    bzw. sich umgehend selbst wieder in einen wohldefinierten Zustand versetzen.
    Ansonsten bin ich allerdings auch ein Freund von ausgiebigem Testen mit vielen Assertions anstatt Taktzyklen für Tests zu verschwenden,
    die bei korrekter Programmierung nicht negativ ausfallen können.

    Gruss,
    Finn


  • Mod

    Finnegan schrieb:

    SeppJ schrieb:

    Prüfen auf Logikfehler zur Laufzeit? Nein, nie. Wozu programmiere ich denn in C++, bloß um dann die Kindersicherung einzuschalten? Dann habe ich die falsche Sprache für das Projekt gewählt.

    Benutzereingaben werden vor der Verarbeitung genauestens geprüft, aber nicht die Tatsache, ob der Programmierer in der Lage ist, ein korrektes Programm zu schreiben.

    Für viele Programme, die in C++ geschrieben werden ist das ein berechtigter Einwand, es gibt allerdings auch Einsatzgebiete,
    die eine besonders hohe Programmstabilität erfordern und wo man selbst bei einem programmierfehler nicht kommentarlos aussteigen sollte:
    z.B. für medizinische Geräte, besonders wenn diese Patienten überwachen oder Ärzte bei Eigngriffen unterstützen, Steuersoftware für technische Anlagen
    oder Fahrzeuge jeglicher Art (Flugzeuge, Autos, oder ... Ariane 5 anyone? ;))

    Es wurde ja danach gefragt, was wir machen, nicht was wir uns vorstellen können. Wie gesagt, wäre der hier geschilderte Fall einer, wo ich niemals prüfen würde und erst recht nicht aus den geschilderten Gründen. Aber ich programmiere auch keine Steuerungen für medizinische Geräte.



  • SeppJ schrieb:

    Die Chance ist hoch, dass ich C++ für Projekte wähle, bei denen ich eben keine überflüssigen Prüfungen aufgebrummt bekommen will. Wenn ich aber ohnehin überflüssige Überprüfungen einprogrammiere, dann kann ich auch gleich eine Sprache wählen, bei der dies schon mit eingebaut ist. Das ist bei so ziemlich allen weniger maschinennahen Sprachen der Fall.

    Das impliziert dass C++, bei Projekten, wo der Grossteil des Codes nicht absolut performancekritisch ist, grundsätzlich "die falsche Sprache" ist. Ich sehe das anders. Ich denke C++ hat auch andere wichtige Vorteile gegenüber anderen Sprachen. Wie z.B. deterministische Finalisierung.

    ps:

    SeppJ schrieb:

    Wie gesagt, wäre der hier geschilderte Fall einer, wo ich niemals prüfen würde und erst recht nicht aus den geschilderten Gründen.

    Auch kein assert() ?



  • SeppJ schrieb:

    Es wurde ja danach gefragt, was wir machen, nicht was wir uns vorstellen können. Wie gesagt, wäre der hier geschilderte Fall einer, wo ich niemals prüfen würde und erst recht nicht aus den geschilderten Gründen. Aber ich programmiere auch keine Steuerungen für medizinische Geräte.

    Jo, klang ein wenig so als wäre das eine allgemeine Aussage zu C++.
    Bei dem gegebenen Beispiel von Eisflamme muss ich allerdings sagen,
    dass ich mich, ohne den Kontext zu kennen, nur schwer zurückhalten
    kann in dem Fall 0 zurückzugeben. Das springt einen förmlich an 🙂
    Summe von nichts ist 0 - damit könnte ich gut leben... führt nachher
    auch zu wenig Widersprüchen, wenn man anfängt Summen von Summen zu bilden.

    Finnegan


  • Mod

    Finnegan schrieb:

    Jo, klang ein wenig so als wäre das eine allgemeine Aussage zu C++.
    Bei dem gegebenen Beispiel von Eisflamme muss ich allerdings sagen,
    dass ich mich, ohne den Kontext zu kennen, nur schwer zurückhalten
    kann in dem Fall 0 zurückzugeben. Das springt einen förmlich an 🙂
    Summe von nichts ist 0 - damit könnte ich gut leben... führt nachher
    auch zu wenig Widersprüchen, wenn man anfängt Summen von Summen zu bilden.

    Ich hasse 0 als Rückgabewert für Fehler. Das macht nur Sinn, wenn 0 kein gültiger Wert sein kann. Aber 0 kann sehr realistisch die Summe einer Gruppe von Zahlen sein. Das führt zu dem gleichen Problem, weswegen man atoi nicht vernünftig benutzen kann. Nicht nur dass man den Fehlerstatus prüfen muss, man kann ihn nicht einmal sicher erkennen!

    Abgesehen davon, ist ein Fehlerstatus im Rückgabewert allgemein fast immer doof. Man muss den Code mit lauter

    if (funktion(blah) == fehlerstatus)
    {
      fehlerbehandlung;
      hier;
      und;
      jetzt;
    }
    

    verschandeln. Exceptions wurden aus gutem Grund erfunden!



  • @SeppJ
    Die zurückgegebene Null wäre hier ja kein "Rückgabewert für Fehler", sondern einfach ein Wert, von dem man annimmt, dass das restliche Programm damit weitermachen kann, ohne schlimmen Unsinn zu bauen.
    Um zu wissen ob das eine sinnvolle Annahme ist, müsste man natürlich etwas mehr über das Programm wissen.

    Quasi so wie man aus einer GetTranslatedText(string id, string language) Funktion, in Fällen wo id nicht gefunden wird, oft einfach "Text '" + id + "' not found!" zurückgeben kann.


  • Mod

    Dann sollte es etwas auffälligeres sein. 0xDEADEAD oder 0xFFFFFFFF oder ähnlich. Dann sieht man, wie beim "Text not found", dass etwas falsch lief.

    Viele Edits: Irgendwie habe ich es heute nicht so mit Rechtschreibung.



  • Hi,

    danke für die Diskussion!

    Also Crashdumps lasse ich mir auch erzeugen wie vorgeschlagen. pdb-Dateien pro Release merke ich mir und ich nutze CrashRprt, das mir automatisch den Dump zukommen lässt.

    Exceptions nutze ich zurzeit leider viel zu wenig, ich gehe oft davon aus, dass alles einfach funktioniert und ich das "schon richtig gemacht hab". Das stimmt auch fast immer, aber dann kommt halt doch mal irgendwo ein Fehler, der zwar ge-crash-dumpt wird, aber dann bringt mir der Crashreport manchmal nichts, weil der Fehler in nt.dll oder so steckt. 😞 Da steckt er natürlich nicht, wird nur so angezeigt.

    Da frage ich mich halt, was ich verbessern kann, um sicher zu gehen später auch alle Crashs rauszukriegen. Logging wäre sicher eine Option, da manche Kunden regelmäßig Crashs miterleben und andere wiederum nie. Das ist sehr lästig. Denen könnte ich anbieten mal mit Logging zu starten oder so was...



  • Hier sind noch zwei Videos von John Lakos:
    https://channel9.msdn.com/Events/CPP/C-PP-Con-2014/Defensive-Programming-Done-Right-Part-I
    https://channel9.msdn.com/Events/CPP/C-PP-Con-2014/Defensive-Programming-Done-Right-Part-II

    Soweit ich mich erinnere, phi­lo­so­phie­rt er auch über das Thema dieser Diskussion.



  • SeppJ schrieb:

    Ich hasse 0 als Rückgabewert für Fehler. Das macht nur Sinn, wenn 0 kein gültiger Wert sein kann. Aber 0 kann sehr realistisch die Summe einer Gruppe von Zahlen sein. Das führt zu dem gleichen Problem, weswegen man atoi nicht vernünftig benutzen kann. Nicht nur dass man den Fehlerstatus prüfen muss, man kann ihn nicht einmal sicher erkennen!

    Ja, das sehe ich auch so, aber er Grund warum ich hier 0 zurückgeben würde ist nicht, dass 0 ein Fehlerstatus ist, sondern eben ein gültiger und sinnvoller Wert.
    Hier wird schließlich die Summe von Zahlen in einer Menge gebildet, und man kann durchaus argumentieren dass die Summe aller Zahlen in der leeren Menge 0 ist, bzw. dass die Summe aller Zahlen in einer nicht existierenden Menge ebenfalls 0 ist.
    In diesem Fall hätte die Funktion einfach keinen Fehler auf den sie laufen könnte. Das funktioniert aber nur, weil eben 0 ein gültiger Wert ist, der zu keinen logischen Widersprüchen führt. Hätte ich z.B. eine Funktion, die mir die dritte Zahl im fünften Set zurückgeben soll würde ich selbstverständlich auch einen Fehler werfen wenn diese nicht existiert.

    Finnegan


Anmelden zum Antworten