Wieviel Kontrolle ist empfohlen



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



  • volkard schrieb:

    Christoph schrieb:

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

    (s/wächst/schrumpft/)

    Nein, ich meinte "wächst". Dann liest Zeile 3 nämlich noch Müll (wegen dem ungültigen Index), das if in Zeile 5 geht aber davon aus, dass der Index im Range liegt.



  • Gut, mein letzter Beitrag war ein Griff ins Klo, gebe ich zu. Ohne entsprechende Synchronisierungsmöglichkeiten (locken war ja nicht "erlaubt") gehts halt doch nicht.

    volkard schrieb:

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

    Verlagert das Problem lediglich zwischen Zeile 4 und 6, nachdem nach der Überprüfung etwas entfernt werden könnte.

    Ich wollte aber eigentlich mit dem Argument de thread-sicheren Datenstrukturen darauf hinaus, dass man sich diese "verbaut", wenn man eine Zugriffsmöglichkeit ohne Exceptions (Stichwort: throw()) anbietet. Für die paar Fälle in denen man den Index-Bereich "weiß" zahlt sich eine zusätzliche Zugriffsmöglichkeit nicht aus. Es besteht bei 2 Methoden aber trotzdem die Gefahr, dass Fehler verschluckt werden.



  • exceptions` schrieb:

    Ich wollte aber eigentlich mit dem Argument de thread-sicheren Datenstrukturen darauf hinaus, dass man sich diese "verbaut", wenn man eine Zugriffsmöglichkeit ohne Exceptions (Stichwort: throw()) anbietet.

    erklär das mal auf russisch. so versteh ichs nicht.
    außerdem widerspreche ich mal prophylaktisch.


Anmelden zum Antworten