Wieviel Kontrolle ist empfohlen



  • rlln schrieb:

    exceptions` schrieb:

    Es muss ja schlechter Stil sein, denn es erinnert zu stark an Java.

    Java kennt genauso Assertions wie c++.

    Ich habe ja auch nichts anderes behauptet, asserts verwende ich in Java aber auch nicht in "öffentlichen APIs". Sie haben halt ein anderes Anwendungsgebiet:

    void foo() {
        for (...) {
            if (...)
                return;
        }
        assert false; // Execution should never reach this point!
    }
    

    volkard schrieb:

    und natürlich können die dafür notwendigen daten in einem deiner kaputten arrays liegen.

    Da ist es natürlich vernünftiger ich lese Blödsinn aus meinem kaputten Array, verursache undefined behaviour und versuche damit die Datenbank zu schließen. Wenn ich entsprechend mitlogge brauche ich auch keine 2 oder mehr Arbeitstage um den Fehler zu finden, da ich dann auch sofort sehen kann, dass 2 Exceptions geworfen wurden (z.B: std::uncaught_exception).

    siehste ja hier an dem exceptionstroll.

    Hehe, jetzt ist man also ein Troll, wenn man nicht deine Meinung teilt.



  • letzte antwort.

    exceptions` schrieb:

    Hehe, jetzt ist man also ein Troll, wenn man nicht deine Meinung teilt.

    nö. aber wenn man von ner anderen sprache aus schaut und als c++-nube versucht, mit den großen zu reden und dabei kontinuierlich unfug verzapft. nicht einer deiner gedanken ist stichhaltig. indexgrenzenüberschreitungen sind nix, was man verhätscheln muss. die rottet man einfach aus und gut ists. du machst hier nen clown um ein nichtexistierendes problem. da ist auch keine diffuse ein-zu-zehn-millionen-chance, wie Bock sie befürchtet, daß man doch mal auf so einen fehler läuft. diese idee enspringt dem alten glauben an die bugs, die wie naturgeister einfach dazugehören und das beste, was man machen kann, ist, dafür zu sorgen, daß sie einen nicht gerade umbringen.
    deine argumentation ist: "aber wenn mal eine überschreitung beim kunden vorkommt..."
    und die ist inkompatibel zu "es kommt beim kunden keine vor".

    vorher gewinne ich mehrmals den lotto-jackpot, obwohl ich nicht spiele. und komm mir bloß nicht mit "du kannst nicht gewinnen, wenn du nicht spielst". darauf komme ich mit "aber was ist in dem ganz unwahrscheinlichen fall, daß ich doch gewinne, ohne zu spielen"?



  • übelst



  • volkard schrieb:

    nö. aber wenn man von ner anderen sprache aus schaut und als c++-nube versucht, mit den großen zu reden und dabei kontinuierlich unfug verzapft.

    Ich hab genauso, wie viele andere hier, mit C++ angefangen und genauso alle Bücher gelesen, die es zu lesen gibt (Effective bzw. Exceptional C++-Reihe, Modern C++ Design, ...) und war bis vor ein, zwei Jahren auch öfter hier im C++ Forum tätig. Nebenbei weiß ich auch noch, dass ich dir mal im IRC erklärt habe, warum man Template-Funktionen überladen und nicht spezialisieren soll, wirst dich aber sicher nicht mehr daran erinnern und selbst wenn du es abstreitest ist mir das auch egal. Aber nachdem ich die Sprache gewechselt habe, muss ich ja ein c++-nube sein ..

    diese idee enspringt dem alten glauben an die bugs, die wie naturgeister einfach dazugehören und das beste, was man machen kann, ist, dafür zu sorgen, daß sie einen nicht gerade umbringen.
    deine argumentation ist: "aber wenn mal eine überschreitung beim kunden vorkommt..."
    und die ist inkompatibel zu "es kommt beim kunden keine vor".

    Ich gebe zu ich habe wirklich schon ewig keine Software benutzt, die ein Maintenance Release oder sonstige BugFixes benötigt, aufgrund ähnlich absoluter Sicherheit. Naja gut, außer mein derzeitiges Betriebssystem Ubuntu 6.06, ach ja und mein Browser natürlich auch Firefox 1.5.0.6. Bevor ichs vergesse natürlich auch noch meine IDE Eclipse 3.2, .... 🙄

    vorher gewinne ich mehrmals den lotto-jackpot, obwohl ich nicht spiele. und komm mir bloß nicht mit "du kannst nicht gewinnen, wenn du nicht spielst". darauf komme ich mit "aber was ist in dem ganz unwahrscheinlichen fall, daß ich doch gewinne, ohne zu spielen"?

    Dein "Vektor" würde also undefined behaviour verursachen, wenn eine Werbeaktion mit angeblichem Gewinn bei dir eintrudelt ...

    letzte antwort.

    Kann mir relativ egal sein, ob du noch antwortest oder nicht, da sowieso alle jene, die diesen Thread sonst noch lesen, für sich entscheiden wer Recht hat. Ich kann dich sowieso genauso wenig überzeugen, wie du mich.



  • Wann hatte ihr Probleme mit zugriffen hinters Array? Kommt doch so gut wie nie vor.



  • exceptions` schrieb:

    und einmal aus einem destruktor im stack-unwinding

    Man merkt, dass dir die Argumente ausgehen, wenn du davon ausgehst, dass ich im Destruktor Exceptions werfe.

    Also hast du noch nie in deinem Leben den operator[] in einem Destruktor benutzt? Das glaube ich dir nicht.

    Ist also die Frage, was nehme ich eher in kauf, ein Index-Überlauf auf den ich eh im Debug-Modus teste oder das mir irgend wo eingefügte Exceptions mein Programm zerreissen, sowohl im Debug, als auch im Release.

    Nehmen wir mal einen anderen Ansatz, um den Nutzen von Exceptions zu sehen.
    (a) Der Kunde bekommt also Programm A mit Exceptions in []. Programm A kommt zu dem Bug, wo es über den erlaubten Index hinaus lesen will. Also fliegt eine Exception. Der Kunde denkt sich "Kacke, Programm abgestürzt". Also schickt er dir die Fehlermeldung und den Coredump. Nun gehst du das Programm mit Hilfe des Coredumps durch und schaust wo die Index überschreitung fast statt gefunden hat.. Hast du die Stelle gefunden, suchst du den Grund für den Bug und versuchst ihn zu beheben.

    (b) Der Kunde bekommt Programm B ohne Exceptions in []. Programm B kommt zu dem Bug, wo es über den erlaubten Index hinaus lesen will. Also fliegt eine SIGSEG-Exception. Der Kunde denkt sich "Kacke, Programm abgestürzt". Also schickt er dir die Fehlermeldung und den Coredump. Nun gehst du das Programm (in der Debug-Version mit assert oder gar mit Valgrind) mit Hilfe des Core dumps durch und schaust wo die Index überschreitung statt gefunden hat. Hast du die Stelle gefunden, suchst du den Grund für den Bug und versuchst ihn zu beheben.

    Wo ist jetzt der Vorteil von (a) gegenüber (b)? Im Grunde brauchen beide Programmierer ungefähr die gleiche Zeit um das Fehlverhalten zu rekonstruieren. Aber die eigentliche Schwierigkeit ist doch den wirklichen Fehler zu finden und nicht die Auswirkung (Index Überschreitung). Da bietet keine Methode einen Vorteil. Exceptions bieten zusätzliche Unsicherheit (Exception im Dtor) und machen den Code langsamer (ja, ein if in einem []kann einiges kosten. Ich sag nur

    array<T> a(WIRKLICH_GROSZE_ARRAY_LAENGE);
    for(size_t i = 0; i < a.size(); ++i)
      do_sth(a[i]);
    

    ). Also bieten sie nur Nachteile, warum sollte ich sie dann benutzen?



  • @Programm stürzt ab: Nicht jede Sprache hat so eine schlechte Exception behandlung wie C++.



  • ffddg schrieb:

    @Programm stürzt ab: Nicht jede Sprache hat so eine schlechte Exception behandlung wie C++.

    Das war aus User-Sicht geschrieben. Natürlich stürzt es nicht ab in dem Sinne. Aber für den Benutzer ist es egal ob das Programm erst sagt "Exception X gefangen. Programm wird beendet" oder "Programm abgestürzt".

    Was das mit C++ zu tun hat verstehe ich nicht, du aber vermutlich auch nicht.



  • rüdiger schrieb:

    Ist also die Frage, was nehme ich eher in kauf, ein Index-Überlauf auf den ich eh im Debug-Modus teste oder das mir irgend wo eingefügte Exceptions mein Programm zerreissen, sowohl im Debug, als auch im Release.

    Das kannst du so nicht vergleichen, denn wenn du die eine Variante auf Fehlerfreiheit testest musst du das klarerweise auch bei der anderen machen um einen fairen Vergleich zu erhalten. Insofern treten in dem Fall (alles läuft perfekt) auch bei Exceptions im Release Mode keine Fehler auf.

    rüdiger schrieb:

    Nehmen wir mal einen anderen Ansatz, um den Nutzen von Exceptions zu sehen.
    (a) Der Kunde bekommt also Programm A mit Exceptions in []. Programm A kommt zu dem Bug, wo es über den erlaubten Index hinaus lesen will. Also fliegt eine Exception. Der Kunde denkt sich "Kacke, Programm abgestürzt". Also schickt er dir die Fehlermeldung und den Coredump. Nun gehst du das Programm mit Hilfe des Coredumps durch und schaust wo die Index überschreitung fast statt gefunden hat.. Hast du die Stelle gefunden, suchst du den Grund für den Bug und versuchst ihn zu beheben.

    Ich kann aber die Auswirkung einer Exception selbst bestimmen und so wird halt einfach z.B: nur der derzeitige Dialog abgebrochen, aber nicht die gesamte Anwendung.

    rüdiger schrieb:

    Wo ist jetzt der Vorteil von (a) gegenüber (b)? Im Grunde brauchen beide Programmierer ungefähr die gleiche Zeit um das Fehlverhalten zu rekonstruieren.

    Nein eben nicht, da sich undefined behaviour ja nicht zwangsweise sofort auswirken muss. Es kann mir keiner erzählen, dass er für den Ursprung einer Exception genauso lange suchen muss wie für den Ursprung von UDB.

    rüdiger schrieb:

    Exceptions bieten zusätzliche Unsicherheit (Exception im Dtor)

    Du favorisierst also notfalls UDB im Destruktor, was ja der Fall analog dazu wäre bei gleicher Ausgangssituation? 🙄

    array<T> a(WIRKLICH_GROSZE_ARRAY_LAENGE);
    for(size_t i = 0; i < a.size(); ++i)
      do_sth(a[i]);
    

    Hier wird ohnehin do_sth maßgeblich sein für die Performance.



  • rüdiger schrieb:

    ffddg schrieb:

    @Programm stürzt ab: Nicht jede Sprache hat so eine schlechte Exception behandlung wie C++.

    Das war aus User-Sicht geschrieben. Natürlich stürzt es nicht ab in dem Sinne. Aber für den Benutzer ist es egal ob das Programm erst sagt "Exception X gefangen. Programm wird beendet" oder "Programm abgestürzt".

    Was das mit C++ zu tun hat verstehe ich nicht, du aber vermutlich auch nicht.

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

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

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



  • Da hat der exceptions` schon Recht, mit einer Exception kann ich machen was ich will, mit undef. Verhalten nichts.

    Exception abfangen und dann:
    a) Programm beenden mit Fehlercode
    b) Fehler-Dialog anzeigen lassen, das zB die Input-Daten korrupt sind
    c) es nochmal versuchen mit einer etwas fehlerfreieren Methode
    usw.

    Dafür hat man halt die schlechtere Laufzeit. Ist doch immer das selbe: Sicherheit ~ 1 / Laufzeit

    Da ist es immer besser zwei Methoden anzubieten, eine schnelle aber unsichere, eine langsame aber sichere. So kann sich der Programmierer selbst entscheiden was er will.

    Ich würde den op[] als die schnellere Methode anbieten, und eine Methode get(index) als die sichere.



  • rüdiger schrieb:

    Nehmen wir mal einen anderen Ansatz, um den Nutzen von Exceptions zu sehen.
    (a) Der Kunde bekommt also Programm A mit Exceptions in []. Programm A kommt zu dem Bug, wo es über den erlaubten Index hinaus lesen will. Also fliegt eine Exception. Der Kunde denkt sich "Kacke, Programm abgestürzt". Also schickt er dir die Fehlermeldung und den Coredump. Nun gehst du das Programm mit Hilfe des Coredumps durch und schaust wo die Index überschreitung fast statt gefunden hat.. Hast du die Stelle gefunden, suchst du den Grund für den Bug und versuchst ihn zu beheben.

    Ich kann aber die Auswirkung einer Exception selbst bestimmen und so wird halt einfach z.B: nur der derzeitige Dialog abgebrochen, aber nicht die gesamte Anwendung.

    Das kann man im Prinzip bei einem Segfault auch. Aber wir gehen ja eh davon aus, das so etwas nicht auftritt und wenn ist der Anwender immer noch der gearschte. Wenn ich die Sicherheit benötige, kann ich ja immer noch die Exception werfende Funktion nehmen. Ich will sie mir nur nicht aufzwingen.

    rüdiger schrieb:

    Wo ist jetzt der Vorteil von (a) gegenüber (b)? Im Grunde brauchen beide Programmierer ungefähr die gleiche Zeit um das Fehlverhalten zu rekonstruieren.

    Nein eben nicht, da sich undefined behaviour ja nicht zwangsweise sofort auswirken muss. Es kann mir keiner erzählen, dass er für den Ursprung einer Exception genauso lange suchen muss wie für den Ursprung von UDB.

    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.

    rüdiger schrieb:

    Exceptions bieten zusätzliche Unsicherheit (Exception im Dtor)

    Du favorisierst also notfalls UDB im Destruktor, was ja der Fall analog dazu wäre bei gleicher Ausgangssituation? 🙄

    okay, da hast du recht. Es führt keine zusätzliche Unsicherheit ein, da man in beiden Fällen UDB im Dtor hat. Es behebt eben nur nicht wie angepriesen UDB in allen Fällen.

    array<T> a(WIRKLICH_GROSZE_ARRAY_LAENGE);
    for(size_t i = 0; i < a.size(); ++i)
      do_sth(a[i]);
    

    Hier wird ohnehin do_sth maßgeblich sein für die Performance.

    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.



  • ffdddg schrieb:

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

    was deckt es nicht ab?



  • 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 🙄 ...


Anmelden zum Antworten