Wieviel Kontrolle ist empfohlen



  • rüdiger schrieb:

    Das kann man im Prinzip bei einem Segfault auch.

    Es muss sich ja nicht zwangsweise ein Segfault ergeben ...

    doch, ich glaube das habe ich gerade getan. Zum einen kann man den Debugger mit Cores füttern (du musst ja vermutlich eh suchen, wo die Exception geworfen wurde) oder Werkzeuge wie valgrind benutzen.

    Ich kann mich ja jetzt täuschen, aber CoreDumps stehen doch auch nur im Debug Mode zur Verfügung. Das Problem dabei ist, dass du den Fehler aber eben selbst erstmal im Debug-Mode nachstellen musst, um einen CoreDump zur Verfügung zu haben.

    Es behebt eben nur nicht wie angepriesen UDB in allen Fällen.

    Es bleibt aber in keinem Fall unentdeckt, bzw. ist eben sofort ersichtlich. Falls man es denn unbedingt benötigt, kann man vorm Werfen der Exception ja auch überprüfen ob nicht bereits eine geworfen wurde ..

    wie kommst du darauf? Schleifen wie

    for(size_t i = 0; i < a.size(); ++i)
      n += a[i];
    

    haben ja nicht unbedingt Seltenheitswert. Außerdem kann der Compiler mit dem if keinen SIMD Code generieren etc.

    In dem Fall bleiben dir ja immer noch Iteratoren ..



  • doch, ich glaube das habe ich gerade getan. Zum einen kann man den Debugger mit Cores füttern (du musst ja vermutlich eh suchen, wo die Exception geworfen wurde) oder Werkzeuge wie valgrind benutzen.

    Ich kann mich ja jetzt täuschen, aber CoreDumps stehen doch auch nur im Debug Mode zur Verfügung. Das Problem dabei ist, dass du den Fehler aber eben selbst erstmal im Debug-Mode nachstellen musst, um einen CoreDump zur Verfügung zu haben.

    ne, du kannst auch so CoreDumps erzeugen lassen.

    Es behebt eben nur nicht wie angepriesen UDB in allen Fällen.

    Es bleibt aber in keinem Fall unentdeckt, bzw. ist eben sofort ersichtlich. Falls man es denn unbedingt benötigt, kann man vorm Werfen der Exception ja auch überprüfen ob nicht bereits eine geworfen wurde ..

    Mit der Problemdiagnose musst du dich ja eh noch auseinandersetzen. Egal ob du eine Exception hast oder nicht.

    wie kommst du darauf? Schleifen wie

    for(size_t i = 0; i < a.size(); ++i)
      n += a[i];
    

    haben ja nicht unbedingt Seltenheitswert. Außerdem kann der Compiler mit dem if keinen SIMD Code generieren etc.

    In dem Fall bleiben dir ja immer noch Iteratoren ..

    Und wenn die über den Index schreiben? Also bist du eh nur für halbe Sicherheit? Gut, dann kann ich mir auch Exceptions in [] sparen ...



  • Und wenn die über den Index schreiben? Also bist du eh nur für halbe Sicherheit? Gut, dann kann ich mir auch Exceptions in [] sparen ...

    Das kannst du so nicht vergleichen, sondern eher mit:

    std::vector<std::string> strings; // ...
    
    std::string& s = strings[0];
    strings.resize(WIRKLICH_GROSSE_ARRAY_LAENGE);
    
    // s wird wohl ungültig sein
    

    Gegen sowas kann man sich nicht absichern, dafür fehlt in C++ der Garbage Collector :p (darauf brauchst jetzt aber nicht eingehen ..).



  • pfff, war ja klar, das du nur rumtrollen wolltest.



  • pfff, war ja klar, das du nur rumtrollen wolltest.

    Derartige Behauptungen sind ja auch viel bequemer als zu argumentieren. Der Smiley war nicht grundlos da ..



  • exceptions` schrieb:

    pfff, war ja klar, das du nur rumtrollen wolltest.

    Derartige Behauptungen sind ja auch viel bequemer als zu argumentieren. Der Smiley war nicht grundlos da ..

    Du willst doch gar nicht diskutieren oder was sollte der Code?

    Wo soll ich da bitte argumentieren. Aber im Grunde willst du eh nur rumlaufen und rufen "C++ ist schlecht". Mach das bitte woanders, danke.



  • Du willst doch gar nicht diskutieren oder was sollte der Code?

    Ich wollte lediglich darauf hinaus, dass ungültige Iteratoren ein Problem sind, die sich nicht auf die Verantwortung des Programmiers der Klasse Vektor "niederwälzen" lässt.

    typedef /* ... */ Iterator;
    for (Iterator it = vec.begin(); it != vec.end(); ++i) {
        // ...
    }
    

    Man hat hierauf einfach keinen Einfluss, da die Abbruchbedingung nicht vom Entwickler der Klasse Vektor festgelegt wird. Man kann also nichtmal Iteratoren basteln, die selbst prüfen ob sie am Ende angelangt sind. Ich will es ja nicht zwangsweise gutheißen, aber darauf hat man eben keinen Einfluss, insofern kannst du das auch nicht mit einem operator[] vergleichen.

    Unregistrierte, die C++ nicht anhimmeln, werden anscheinend gern sehr voreilig als Trolle bezeichnet 🙄 ...



  • exceptions` schrieb:

    Du willst doch gar nicht diskutieren oder was sollte der Code?

    Ich wollte lediglich darauf hinaus, dass ungültige Iteratoren ein Problem sind, die sich nicht auf die Verantwortung des Programmiers der Klasse Vektor "niederwälzen" lässt.

    Genauso wie die falsche Benutzung von operator[].

    typedef /* ... */ Iterator;
    for (Iterator it = vec.begin(); it != vec.end(); ++i) {
        // ...
    }
    

    Man hat hierauf einfach keinen Einfluss, da die Abbruchbedingung nicht vom Entwickler der Klasse Vektor festgelegt wird. Man kann also nichtmal Iteratoren basteln, die selbst prüfen ob sie am Ende angelangt sind. Ich will es ja nicht zwangsweise gutheißen, aber darauf hat man eben keinen Einfluss, insofern kannst du das auch nicht mit einem operator[] vergleichen.

    Wohin ein operator zeigt ist ja egal, so lange man ihn nicht dereferenziert. Man kann ihn also wunderbar mit dem operator[] vergleichen.

    Unregistrierte, die C++ nicht anhimmeln, werden anscheinend gern sehr voreilig als Trolle bezeichnet 🙄 ...

    Nein, Leute die offensichtlich nicht diskutieren wollen werden gerechtfertigt als Trolle bezeichnet.



  • BTW:

    ffdddg schrieb:

    Wenn ich z.B. nen Server hab kann ich in Java sowas machen

    try {
       ...
       return doServiceHandling(request);
    } catch (Throwable e) {
       log(e);
       return "error";
    }
    

    ...und das ist sehr schlecht. Bei einem Throwable könntest Du nicht nur Exceptions fangen, sondern auch Errors. Die hinterlassen die JVM in einem nichtdefinierten Zustand und sollten deshalb niemals gefangen werden. Es gibt für Errors keine adäquate Fehlerbehandlung.



  • btw. ist nur so eine Nebenfrage, aber die Performance leidet doch nur wenn eine Exception erzeugt wird, oder?



  • Zeus schrieb:

    btw. ist nur so eine Nebenfrage, aber die Performance leidet doch nur wenn eine Exception erzeugt wird, oder?

    Nein, auch weil der Compiler den Code zB schlechter optimieren kann (zB kann er ihn nicht in SIMD umwandeln, was erhebliche Performance gewinne bringt) und die if-Bedingung erfordert eine Sprungvorhersage und kann dazu führen, da bei jedem op[] einmal die Pipeline verworfen wird. (Wobei man natürlich auch noch zwei weitere Anweisungen zu einem simplen op[] hinzufügt)



  • Bock schrieb:

    Zum Beispiel, ich habe eine Array Klasse geschrieben. Diese hat eine Überladung für den [] operator.
    Wenn man nun einen größeren Index angibt als es Elemente gibt, sollte ich dann einfach das letzte Element zurückgeben, oder eine Exception werfen?

    Wie bereits erwähnt, eine Exception halte ich nicht unbedingt für sinnvoll. Und das letzte Element zurückgeben? Was machst du dann im Falle eines Containers, der noch gar keine Elemente enthällt? Nullreferenz gibt es ja nicht.
    Ich habe es so gemacht, dass ich ein Dummy Element zurückgebe. Die Anwendung kann somit ohne UB und Exception weiterarbeiten, und mittels einer Log Datei kann ich sehen, durch was der Fehler verursacht wurde. Die Programmlogik mag zwar in einem nicht mehr vollständig definierten Zustand sein, und man kann sich fragen, warum die Anwendung weiterarbeiten soll. Nun, weil es bestimmte Umgebungen gibt, wo es einfach fatal wäre, wenn die Anwendung einfach so abschmiert, obwohl die meisten Teile problemlos weiterarbeiten könnten. Zudem ist es durchaus möglich, durch entsprechende Terminals oder was auch immer die Programmlogik wieder vollständig in einen definierten Zustand zu bringen.
    Das ganze sollte natürlich, wie volkard bereits schrieb, schön in ein assert eingebunden werden, weil es ein logischer Fehler ist, der eigentlich gar nicht existieren darf, und damit im Release kein unnötiger Overhead entsteht.



  • rüdiger schrieb:

    exceptions` schrieb:

    Du willst doch gar nicht diskutieren oder was sollte der Code?

    Ich wollte lediglich darauf hinaus, dass ungültige Iteratoren ein Problem sind, die sich nicht auf die Verantwortung des Programmiers der Klasse Vektor "niederwälzen" lässt.

    Genauso wie die falsche Benutzung von operator[].

    Wenn du Iteratoren mit operator[] vergleichen willst, dann nenn mir doch eine analoge Fehlerüberprüfung zu folgendem Codeausschnitt. Vergiss dabei aber nicht die Aufgabenstellung zu erfüllen von Anfang bis zum Ende zu traversieren (das sag ich jetzt bewusst ..).

    T& operator[int index] {
        if (index >= size()) {
            throw new IndexException(index);
        }
    
        return data[index];
    }
    

    Der Unterschied liegt darin, dass man einen ungültigen Index überprüfen, bzw. besser gesagt "entschärfen" kann, einen ungültigen Iterator nicht.

    Wohin ein operator zeigt ist ja egal, so lange man ihn nicht dereferenziert. Man kann ihn also wunderbar mit dem operator[] vergleichen.

    Nein und warum wurde ja bereits gesagt (siehe oben).



  • rüdiger schrieb:

    ffdddg schrieb:

    Wogegen das C++ catch(...) nicht alles abdeckt.

    was deckt es nicht ab?

    Was es genau war, weiß ich nicht mehr, aber ich hatte schon mal so einen Fall. Ich hab per SendMessage(...) einen Wert eines anderen Fensters abfragen wollen, was zu einem Absturz trotz catch(...) führte, weil dieses noch nicht so weit war. Könnte natürlich an dieser dummen Situation liegen, dass das andere Fenster nicht von mir war, aber mein Programm lief eigentlich im selben Prozess.

    Gregor schrieb:

    BTW:

    ffdddg schrieb:

    Wenn ich z.B. nen Server hab kann ich in Java sowas machen

    try {
       ...
       return doServiceHandling(request);
    } catch (Throwable e) {
       log(e);
       return "error";
    }
    

    ...und das ist sehr schlecht. Bei einem Throwable könntest Du nicht nur Exceptions fangen, sondern auch Errors. Die hinterlassen die JVM in einem nichtdefinierten Zustand und sollten deshalb niemals gefangen werden. Es gibt für Errors keine adäquate Fehlerbehandlung.

    Du kannst durch das loggen des Errors einen Serverrestart veranlassen (vom Admin oder anderem Programm). Ist zwar nicht so toll, aber besser als auf eine freundliche Meldung des OS zu hoffen.

    rüdiger schrieb:

    Zeus schrieb:

    btw. ist nur so eine Nebenfrage, aber die Performance leidet doch nur wenn eine Exception erzeugt wird, oder?

    Nein, auch weil der Compiler den Code zB schlechter optimieren kann (zB kann er ihn nicht in SIMD umwandeln, was erhebliche Performance gewinne bringt) und die if-Bedingung erfordert eine Sprungvorhersage und kann dazu führen, da bei jedem op[] einmal die Pipeline verworfen wird. (Wobei man natürlich auch noch zwei weitere Anweisungen zu einem simplen op[] hinzufügt)

    Sagte ich doch schon 🙄

    dfghs schrieb:

    Wenn er einen Sprung in die andere Richtung erwartet hat, dann wird er auch noch die Pipeline entrümpeln mussen.

    😃 😉



  • ffdddg schrieb:

    rüdiger schrieb:

    ffdddg schrieb:

    Wogegen das C++ catch(...) nicht alles abdeckt.

    was deckt es nicht ab?

    Was es genau war, weiß ich nicht mehr, aber ich hatte schon mal so einen Fall. Ich hab per SendMessage(...) einen Wert eines anderen Fensters abfragen wollen, was zu einem Absturz trotz catch(...) führte, weil dieses noch nicht so weit war. Könnte natürlich an dieser dummen Situation liegen, dass das andere Fenster nicht von mir war, aber mein Programm lief eigentlich im selben Prozess.

    Hört sich eher danach an, das du eine C API benutzt hast (SendMessage -> WinAPI). Die wirft natürlich keine Exception.



  • exceptions` schrieb:

    Wenn du Iteratoren mit operator[] vergleichen willst,

    Nein, das will ich eigentlich nicht. Ich will dich und Leser dieses Threads nur vor Pseudosicherheit durch Exceptions in op[] bewahren.

    dann nenn mir doch eine analoge Fehlerüberprüfung zu folgendem Codeausschnitt. Vergiss dabei aber nicht die Aufgabenstellung zu erfüllen von Anfang bis zum Ende zu traversieren (das sag ich jetzt bewusst ..).

    Da finde ich natürlich keinen vernünftigen weg. Aber ich finde es auch nicht vernünftig, eine Exception in op[] zu werfen 🙂



  • ffdddg schrieb:

    Gregor schrieb:

    BTW:

    ffdddg schrieb:

    Wenn ich z.B. nen Server hab kann ich in Java sowas machen

    try {
       ...
       return doServiceHandling(request);
    } catch (Throwable e) {
       log(e);
       return "error";
    }
    

    ...und das ist sehr schlecht. Bei einem Throwable könntest Du nicht nur Exceptions fangen, sondern auch Errors. Die hinterlassen die JVM in einem nichtdefinierten Zustand und sollten deshalb niemals gefangen werden. Es gibt für Errors keine adäquate Fehlerbehandlung.

    Du kannst durch das loggen des Errors einen Serverrestart veranlassen (vom Admin oder anderem Programm). Ist zwar nicht so toll, aber besser als auf eine freundliche Meldung des OS zu hoffen.

    Es ist eine Fehlannahme, dass man an dieser Stelle noch verlässlich loggen kann.



  • catch(...) fängt im Normalfall keine CPU Exceptions ab.



  • Gregor schrieb:

    ffdddg schrieb:

    Du kannst durch das loggen des Errors einen Serverrestart veranlassen (vom Admin oder anderem Programm). Ist zwar nicht so toll, aber besser als auf eine freundliche Meldung des OS zu hoffen.

    Es ist eine Fehlannahme, dass man an dieser Stelle noch verlässlich loggen kann.

    KAnn ich mich dann darauf verlassen, dass der Error geworfen wird?



  • ffddds schrieb:

    Gregor schrieb:

    ffdddg schrieb:

    Du kannst durch das loggen des Errors einen Serverrestart veranlassen (vom Admin oder anderem Programm). Ist zwar nicht so toll, aber besser als auf eine freundliche Meldung des OS zu hoffen.

    Es ist eine Fehlannahme, dass man an dieser Stelle noch verlässlich loggen kann.

    KAnn ich mich dann darauf verlassen, dass der Error geworfen wird?

    Wenn ein Error geworfen wird, wird er geworfen, keine Frage. Das heißt aber noch lange nicht, dass es nicht andere Möglichkeiten gibt, eine JVM zum Absturz zu bringen. Wenn die JVM z.B. irgendwo nen Fehler in ihrem nativen Code hat, dann kann sie natürlich abstürzen, ohne dass Du etwas davon mitkriegen könntest. ...gleiches gilt, wenn man irgendwelche Bibliotheken nutzt, die nativen Code über JNI einbinden.


Anmelden zum Antworten