Wieviel Kontrolle ist empfohlen



  • exceptions` schrieb:

    Was machst du dann, wenn der Index ungültig ist, UDB?

    jup.

    Und sag mir jetzt nicht, dass du im Debug-Mode eh ein assert hast, denn wie ich bereits gesagt habe, heißt Release-Mode ja nicht per Definition, dass keine Fehler mehr auftreten können. Das klingt für mich irgendwie danach als würdest du die Fehler "verschlucken" ...

    ich mach halt die programmierfehler weg.



  • volkard schrieb:

    Und sag mir jetzt nicht, dass du im Debug-Mode eh ein assert hast, denn wie ich bereits gesagt habe, heißt Release-Mode ja nicht per Definition, dass keine Fehler mehr auftreten können. Das klingt für mich irgendwie danach als würdest du die Fehler "verschlucken" ...

    ich mach halt die programmierfehler weg.

    Ich auch, allerdings muss ich bei Exceptions beinahe blind sein, um sie zu übersehen.



  • Ich überschwemme meine öffentliche Schnittstelle ungern mit redundanten Methoden. Beide erledigen im Prinzip die selbe Aufgabe, nur eine etwas restriktiver. Warum sollte man sich also nicht einfach im Zuge einer einfachen Schnittstelle nicht auf den gemeinsamen Nenner (die restriktivere Variante) entscheiden?

    Dafür wurder Vererbung erfunden. Die Basisklasse ist thread-unsafe, eine Unterklasse ist thread-save.
    Oder man hat halt 2 Vectors, einer ist Thread-unsafe, der andere -safe. Dann noch ein Kopier-Kontruktor für die beiden und alles ist wunderbar 🙂

    PS: Juhu 800 Beiträge 🕶



  • exceptions` schrieb:

    Ich überschwemme meine öffentliche Schnittstelle ungern mit redundanten Methoden. Beide erledigen im Prinzip die selbe Aufgabe, nur eine etwas restriktiver. Warum sollte man sich also nicht einfach im Zuge einer einfachen Schnittstelle nicht auf den gemeinsamen Nenner (die restriktivere Variante) entscheiden?

    Ach ja. Hälst du z.B. std::find auch für redundant? Macht ja im Prinzip das gleiche wie std::find_if... oder std::stable_sort? Nein, halt, der "gemeinsame Nenner" wäre ja std::stable_sort, also sollte man wohl std::sort rausschmeißen, was?



  • DEvent schrieb:

    Dafür wurder Vererbung erfunden. Die Basisklasse ist thread-unsafe, eine Unterklasse ist thread-save.
    Oder man hat halt 2 Vectors, einer ist Thread-unsafe, der andere -safe. Dann noch ein Kopier-Kontruktor für die beiden und alles ist wunderbar.

    Dafür hat man wenn schon Schnittstellen zu verwenden und keine Vererbung (oder willst du behaupten eine thread-sichere Datenstruktur ist eine thread-unsichere Datenstruktur - IS-A Principle), geht aber sowieso völlig am Thema vorbei. Threads wurden lediglich deswegen in die Diskussion miteingebunden gebracht um am Argument "man muss nicht immer den Index prüfen" zu rütteln.

    Ach ja. Hälst du z.B. std::find auch für redundant? Macht ja im Prinzip das gleiche wie std::find_if... oder std::stable_sort? Nein, halt, der "gemeinsame Nenner" wäre ja std::stable_sort, also sollte man wohl std::sort rausschmeißen, was?

    Also der Vergleich ist ja jetzt schon etwas weit hergeholt und das weißt du auch selbst ..

    Ich denke aber langsam lässt die Wirkung der Drogen nach und ich sehe ein, dass ein Range-Check inkl. Exception untragbar viel Performance verbrauchen würde. In diesem Falle ist es natürlich absolut gerechtfertigt sich nicht gegen "undefined behaviour" abzusichern.



  • exceptions` schrieb:

    Threads wurden lediglich deswegen in die Diskussion miteingebunden gebracht um am Argument "man muss nicht immer den Index prüfen" zu rütteln.

    ein argument, das ich nicht verstehe. wer um alles in der welt plant denn ernsthaft so ein programm, das zufällig oft funktioniert aber garantiert nicht immer funktioniert, und führt diesen wirklich schlechten stil (nichtsynchronisierte interthreadkommunikation) dann als argument auf, um einen anderen schlechten stil (exceptions gegen programmierfehler) zu verteidigen? womit habe ich das verdient?



  • Nachdem du es anscheinend nich verstehen willst, frage ich dich, welchen Vorteil besitzt eine zusätzliche Zugriffsmöglichkeit, die keine Exceptions wirft? Komm mir jetzt aber nicht mit fadenscheinigen Argumenten wie Performance, ...

    volkard schrieb:

    schlechten stil (exceptions gegen programmierfehler)

    Natürlich ist es schlechter Stil, wenn man sich undefined behaviour und stundenlanges Debuggen ersparen will, weil man den Fehler nicht findet. Es muss ja schlechter Stil sein, denn es erinnert zu stark an Java. 🙄



  • Aiaiai, was habe ich hier nur angerichtet 😉

    An sowas wie Multithreating hatte ich noch gar nicht gedacht.
    Mir ging es im Endeffekt nur darum, ob man wirklich alles kontrollieren muss
    oder manchmal auch einfach davon ausgehen kann ob etwas funktioniert(und auf die
    Intelligenz des Programmierers vertraut)

    Meine Idee war nur, wenn ich so eine Indexüberprüfung nicht einbaue, dann geht das
    wenn es hochkommt vlt jedes 10000000 mal daneben, aber dieses eine Mal kann ich ja verhinden, und eine if abfrage ist ja nicht wirklich teuer(in Assembler glaube ich einen cmp Befehl und danach ein Register auslesen, das dürften nur 4 Takte sein)

    Ich bin halt gerne auf der sicheren Seite 🙂



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



  • exceptions` schrieb:

    Komm mir jetzt aber nicht mit fadenscheinigen Argumenten wie Performance, ...

    doch. viel schlimmer noch, die auch beim kunden exceptionswerfende hat keinerlei vorteile.

    exceptions` schrieb:

    Natürlich ist es schlechter Stil, wenn man sich undefined behaviour und stundenlanges Debuggen ersparen will, weil man den Fehler nicht findet.

    im debug-mode ist doch assert an (bessergesagt ein aufgepimptes ASSERT). wegen indexgrenzenüberschreitungen gibr es kein stundenlanges debuggen. das war mal, als man noch wie in C programmiert hat. die indexgrenzenfehlersuche der letzten jahre hat mich zusammen vielleicht ne stunde gekostet und liegt nur dran, daß ich netterweise fremde programme durchgesehen hab.
    das ist so ein phänomen, wie das mit den speicherlöchern, die in modernem C++ so rar sind, wie naturblonde chinesen in bielefeld. sie sind sicher kein argument, nen garbage collector zu bauen. und das wird auch nicht dadurch geändert, daß anfänger die ersten jahre probleme damit haben.

    exceptions` schrieb:

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

    es ist schlechter stil, weil es zu nicht wegzudiskutierenden kosten ein nicht-problem "repariert". ich will dich mal sehen, wenn du wegen eines programmierfehlers (und dazu gehört deine nichtsynchronisierte komnmunikation) die exception zweimal fliegen läßt, einmal "normal" und einmal aus einem destruktor im stack-unwinding heraus. machste assert an, siehste nur die erste. die ist nicht kritisch. machste assert aus, terminiert das programm, statt die exception in der main zu fangen. und da du das phänomen nicht kennst, gehen erstmal zwei arbeitstage drauf, das zu finden. vermutlich viel mehr, weil du ja mit deinem programmierfehler sporadische exceptions erzeugst.
    ein einfaches sofortiges und konsequentes asserten im debug-mode ist da die bessere taktik, glaub mir da einfach.



  • Mir ging es im Endeffekt nur darum, ob man wirklich alles kontrollieren muss
    oder manchmal auch einfach davon ausgehen kann ob etwas funktioniert(und auf die
    Intelligenz des Programmierers vertraut)

    Ich betrachte das eher von der anderen Seite und halte es nicht für eine großartige Darstellung der eigenen Intelligenz wenn man Klassen entwickelt, die unter Umständen undefined behaviour verursachen. Komischerweise wird es anscheinend bei Collections/Container geduldet, was ich einfach für ein Unding halte.

    im debug-mode ist doch assert an (bessergesagt ein aufgepimptes ASSERT). wegen indexgrenzenüberschreitungen gibr es kein stundenlanges debuggen. das war mal, als man noch wie in C programmiert hat. die indexgrenzenfehlersuche der letzten jahre hat mich zusammen vielleicht ne stunde gekostet und liegt nur dran, daß ich netterweise fremde programme durchgesehen hab.

    Das Problem dabei ist aber, dass erstmal der Fehler reproduziert werden muss ohne jegliche Informationen ausser den Angaben vom Kunden und die werden mehr als dürftig sein. Daraus ergibt sich auch gleich der Vorteil der "beim-Kunden-exceptionwerfenden-Version" durch z.B: zusätzliche Log-Datein, die er beim Bug Report angeben kann (selbst ohne Stack Trace gibt es einen Anhaltspunkt).

    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.



  • exceptions` schrieb:

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

    Java kennt genauso Assertions wie c++.



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

    wenn du nicht im destruktor datenbanken schließt, socket-partnern bescheidsagst, file-lockings entfernst, temp-dateien löscht und so fort, dann haste was ganz entscheidendes nicht verstanden. und natürlich können die dafür notwendigen daten in einem deiner kaputten arrays liegen.



  • 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?

    falsches forum, wenn du eine c++-spezifische antwort suchst. siehste ja hier an dem exceptionstroll.



  • 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?


Anmelden zum Antworten