Wieviel Kontrolle ist empfohlen



  • Moin,

    Auf die Idee mit dem letzten Element zurückgeben bin ich nur gekommen, weil es in der Standart Bibliothek ähnlich behandelt wird.
    Wenn man zum Beispiel einen SubString haben will:

    string s1;
    s1="Hallo";
    
    string s2;
    s2=s1.substr(0,1000); // der Index ist viel zu groß deshalb wird alles von 0 bis Ende zurückgegeben;
    

    Aber zu den Asserts. Wenn ich zum Beispiel einen Array von Vectoren mache und dann ein Modell rendern will, hole ich mir ja alle Informationen aus der Mesh-Datei.
    Da kann es des öfteren mal passieren, dass ein Index überschritten wird.
    Das könnte aber noch in der Final Version passieren, also musss ich ja irgendwie reagieren können.

    Ich denke ich werde mal eine Exception einbauen.



  • Exception sind nicht dazu da, um Plausibilitätsprüfungen durchzuführen.
    In deinem Beispeil steht .substr wenn die das Argument höher ist als der Stringlänge dann nehment die Funktion die maximale Länge des Strings.

    Richtige Verwendung von Exception ist zum Beispiel:
    Wenn du eine Clientprogramm hast und diese auf Daten vom Server wartet, aber sie nicht kommen, dann kannst du mit eine Exception angemessen darauf reagieren, sei es ausweichen auf ein anderen Server, Messagebox "Server nicht erreichbar" oder sonstwas.

    Aber Plausibilitätsprüfungen gehört zu deine Programmieraufgabe.



  • Bock schrieb:

    Ich denke ich werde mal eine Exception einbauen.

    Dann implementier lieber eine Methode ala .at() dafür, so wie es die STL auch macht.

    Im Grunde würde ich, wenn es für dein Programm "normal" ist, über die Array-Größe hinaus zu lesen, keine Exception benutzen. Da Exceptions ja für Ausnahmen und nicht für normales Programmverhalten gedacht sind.



  • Im Grunde würde ich, wenn es für dein Programm "normal" ist, über die Array-Größe hinaus zu lesen, keine Exception benutzen. Da Exceptions ja für Ausnahmen und nicht für normales Programmverhalten gedacht sind.

    Eben, denn im Release-Mode können ja gar keine Fehler auftreten, da kann man sie getrost ignorieren ...



  • Rüdiger meinte ich sollte lieber eine Methode wie at() einbauen.
    Aber diese Methode schmeißt doch eben eine Exeption.

    http://www.cppreference.com/cppstring/at.html

    Instead of attempting to read garbage values
     from memory, the at() function will realize 
    that it is about to overrun the vector and will throw an exception.
    


  • Bock schrieb:

    Rüdiger meinte ich sollte lieber eine Methode wie at() einbauen.
    Aber diese Methode schmeißt doch eben eine Exeption.

    http://www.cppreference.com/cppstring/at.html

    Instead of attempting to read garbage values
     from memory, the at() function will realize 
    that it is about to overrun the vector and will throw an exception.
    

    Da hast du mich missverstanden. Ich meinte das eher so, dass du bevor du operator[] mit einer Exception implementierst, lieber eine Funktion at() mit einer Exception implementieren solltest.



  • rüdiger schrieb:

    Da hast du mich missverstanden. Ich meinte das eher so, dass du bevor du operator[] mit einer Exception implementierst, lieber eine Funktion at() mit einer Exception implementieren solltest.

    Was genau versprichst du dir dadurch? Was hast du von einer Zugriffsfunktion, die Fehler "verschluckt" indem sie keine Exception wirft? Letztendlich musst du dann einfach selbst überprüfen, ob der Index gültig ist und das ist auf Dauer gesehen reiner "boiling-plate" code, der mit Exceptions hätte vermieden werden können.



  • exceptions` schrieb:

    rüdiger schrieb:

    Da hast du mich missverstanden. Ich meinte das eher so, dass du bevor du operator[] mit einer Exception implementierst, lieber eine Funktion at() mit einer Exception implementieren solltest.

    Was genau versprichst du dir dadurch? Was hast du von einer Zugriffsfunktion, die Fehler "verschluckt" indem sie keine Exception wirft? Letztendlich musst du dann einfach selbst überprüfen, ob der Index gültig ist und das ist auf Dauer gesehen reiner "boiling-plate" code, der mit Exceptions hätte vermieden werden können.

    Ich würde in den operator[] ein assert einbauen. So kann man im Debug-Modus prüfen, hat im Release aber keinen Overhead. Wer mehr Sicherheit will kann dann at-nehmen.



  • Achso...

    Vielen Dank für eure Antworten.
    Ich denke ich werde es wie Rüdiger meinte machen, nur halt genau umgekehrt.
    Beim

    operator[]
    

    werde ich eine überprüfung einbauen und eine extra Methode die einfach alles blind macht(im Debug halt noch ein assert).
    So überlegt man sich 2 mal ob man wirklich kein Risiko eingeht.

    mfg Bock



  • also statt beim speichern aus dem editor auf plausibilität zu prüfen, bzw im makefile, es erst bei laden zu machen, halte ich ja schon für befremdlich.
    aber es sogar vom laden zu verschieben auf immer, da muss ich mir erstmal uml-diagramme dazu erstellen, damit ich das genau nachvollziehen kann und eventuell einen fachmann fragen, der durch java 100% objektorientierung kann.



  • exceptions` schrieb:

    rüdiger schrieb:

    Da hast du mich missverstanden. Ich meinte das eher so, dass du bevor du operator[] mit einer Exception implementierst, lieber eine Funktion at() mit einer Exception implementieren solltest.

    Was genau versprichst du dir dadurch? Was hast du von einer Zugriffsfunktion, die Fehler "verschluckt" indem sie keine Exception wirft? Letztendlich musst du dann einfach selbst überprüfen, ob der Index gültig ist und das ist auf Dauer gesehen reiner "boiling-plate" code, der mit Exceptions hätte vermieden werden können.

    Dir scheint nicht klar zu sein dass du oftmals eben nicht prüfen musst ob der Index gültig ist, da du von vorneherein schon weisst dass er nicht ungültig sein kann.



  • finix schrieb:

    Dir scheint nicht klar zu sein dass du oftmals eben nicht prüfen musst ob der Index gültig ist, da du von vorneherein schon weisst dass er nicht ungültig sein kann.

    Selbst in Situationen bei einer simplen Schleife über den gesamten Vektor (std::vector) kann man dank Multi-Threading nicht davon ausgehen, dass man die Index Grenzen derartig 100% weiß. Außerdem tut ihr ja gerade so als würde eine lächerliche Überprüfung mit entsprechender Exception hinterher wirklich Auswirkungen auf die Performance ausmachen ..



  • exceptions` schrieb:

    finix schrieb:

    Dir scheint nicht klar zu sein dass du oftmals eben nicht prüfen musst ob der Index gültig ist, da du von vorneherein schon weisst dass er nicht ungültig sein kann.

    Selbst in Situationen bei einer simplen Schleife über den gesamten Vektor (std::vector) kann man dank Multi-Threading nicht davon ausgehen, dass man die Index Grenzen derartig 100% weiß.

    Soll die Datenstruktur jetzt plötzlich Rücksicht darauf nehmen, wenn jemand beim Thema Multithreading nicht aufgepasst hat?



  • Soll die Datenstruktur jetzt plötzlich Rücksicht darauf nehmen, wenn jemand beim Thema Multithreading nicht aufgepasst hat?

    Eine thread-sichere Datenstruktur? Wie komme ich denn nur auf eine derartig absurde Idee. Da muss ich wohl eingeraucht gewesen sein ..



  • wer garantiert denn, daß die Datenstruktur die Größe nicht gerade nach dem Abprüfen, ob eine exception geworfen werden soll ändert und damit der Index doch noch ungültig wird?

    Und bei jedem Zugriff komplett zu locken ist zu teuer. Lesezugriffe dürfen ja parallel sein. Ergo muß man sich sowieso von außerhalb um Threadsicherheit kümmern.

    Du mußt ganz offensichtlich eingraucht gewesen sein. 😉



  • Jester schrieb:

    wer garantiert denn, daß die Datenstruktur die Größe nicht gerade nach dem Abprüfen, ob eine exception geworfen werden soll ändert und damit der Index doch noch ungültig wird?

    class Vector<T> {
        private:
            // ...
    
        public:
            T operator[int i] {
                T obj = data[i];
    
                if (i >= size) {
                    throw new IndexException(i);
                }
    
                return obj;
            }
    };
    


  • class Vector<T> {
        private:
            // ...
    
        public:
            T operator[int i] {
                T obj = data[i];
    
                if (i >= size) {
                    throw new IndexException(i);
                }
    
                return obj;
            }
    };
    

    du kopierst das objekt erst zweimal, bevor der user es haben darf? ich würd noch nen virenscanner drüberlaufen lassen. und verwirrend ist es auch, wenn Vector<int> v;...;v[0]=0;cout<<v[0]; mal 17 anzeigt.

    class Vector<T> {
        private:
            // ...
            T* data;//zum beispiel
        public:
            T& operator[](size_t i) {
                assert(i<size);
                //assert(i<1000000000);//je nach laune
                return data[i];
            }
    };
    


  • exceptions` schrieb:

    public:
            T operator[int i] {
                T obj = data[i];
    
                if (i >= size) {
                    throw new IndexException(i);
                }
    //...
    

    Dieses if ist schon überflüssig, weil bei ungültigem Index die Zeile 3 zumindest undefiniertes Verhalten und bei nicht-trivialem Copy-Constructor eine Zugriffsverletzung erzeugt.
    Außerdem ist es immer noch genausowenig threadsicher, wenn der Vektor zwischen Zeile 3 und 4 wächst.



  • Christoph schrieb:

    Außerdem ist es immer noch genausowenig threadsicher, wenn der Vektor zwischen Zeile 3 und 4 wächst.

    (s/wächst/schrumpft/)

    gegen problem zwischen den zeilen hab ich doch schon was.

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

    SCNR. 😉



  • exceptions` schrieb:

    class Vector<T> {
        private:
            // ...
    
        public:
            T operator[int i] {
                T obj = data[i];
    
                if (i >= size) {
                    throw new IndexException(i);
                }
    
                return obj;
            }
    };
    

    Was ist, wenn zum Zeitpunkt des lesens noch Müll dort stand und erst vor der Abfrage der Größe ein sinnvoller Wert eingetragen wurde?


Anmelden zum Antworten