Wieviel Kontrolle ist empfohlen



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



  • 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. Für die paar Fälle in denen man den Index-Bereich "weiß" zahlt sich eine zusätzliche Zugriffsmöglichkeit nicht aus.

    Also bitte. Was heißt denn für dich "die paar Fälle"? Single-Threaded Programme? Daten auf die ausschließlich innerhalb eines Worker-Threads zugegriffen wird?

    Und was heißt denn "zahlt sich eine zusätzliche Zugriffsmöglichkeit nicht aus"?

    T at( index )
    {
      check index
      return op[]( index )
    }
    


  • volkard schrieb:

    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.

    Gut, nehmen wir an, wir haben es nun STL-like implementiert und wollen im Zuge einer Multi-Threading Anwendung dem operator[] einen Index-Range Check geben. Was machst du, wenn der Index ungültig ist?

    Und was heißt denn "zahlt sich eine zusätzliche Zugriffsmöglichkeit nicht aus"?

    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?



  • exceptions` schrieb:

    Gut, nehmen wir an, wir haben es nun STL-like implementiert und wollen im Zuge einer Multi-Threading Anwendung dem operator[] einen Index-Range Check geben. Was machst du, wenn der Index ungültig ist?

    irrige annahme.
    der op[] hat kein range-checking (außer mit assert) verdient.
    eine at-funktion würde exceptions werfen. auch im multithreading-fall.


Anmelden zum Antworten