logische Verständnisfrage



  • nki schrieb:

    Oder ist es so, dass es b und c nicht inkrementiert da schon beim ++a der Wert "true" geliefert wird, da ja schon eine Bedingung erfüllt ist, da es ja ODER ist und nicht UND?

    Diese Frage ist die Antwort! 🙂



  • camper schrieb:

    die eingebauten operatoren && und || führen eine sog. kurzschlussauswertung aus: wenn das ergbenis durch den linken operanden bereits bestimmt ist, so wird der rechte operand nicht ausgewertet. das ist im übrigen der grund, warum diese operatoren nicht überladen werden sollten - denn ein überladener operantor ist eine normale funktion, die den üblichen regeln des funktions aufrufs unterliegt (alle operanden werden ausgewertet bevor die funktion aufgerufen wird), es ist nicht möglich, dieses kurzschlussverhalten für eigene operatoren zu erhalten.

    Hmm wo steht, dass das nicht geht? (Der Abschnitt würde mich mal interessieren)
    Ich glaube das nämlich nicht so ganz.

    BR
    Vinzenz



  • evilissimo schrieb:

    camper schrieb:

    die eingebauten operatoren && und || führen eine sog. kurzschlussauswertung aus: wenn das ergbenis durch den linken operanden bereits bestimmt ist, so wird der rechte operand nicht ausgewertet. das ist im übrigen der grund, warum diese operatoren nicht überladen werden sollten - denn ein überladener operantor ist eine normale funktion, die den üblichen regeln des funktions aufrufs unterliegt (alle operanden werden ausgewertet bevor die funktion aufgerufen wird), es ist nicht möglich, dieses kurzschlussverhalten für eigene operatoren zu erhalten.

    Hmm wo steht, dass das nicht geht? (Der Abschnitt würde mich mal interessieren)
    Ich glaube das nämlich nicht so ganz.

    Das folgt direkt aus der Tatsache, dass ein Operator immer durch eine *Funktion* überladen wird (siehe 13.5). Und die Regeln für Funktionen besagen, dass immer alle Argumente ausgewertet werden (wobei die Reihenfolge nicht spezifiziert ist).



  • Dankeschön für die Bestätigungen und für diese gerade laufende, interessante Diskussion 🙂



  • HumeSikkins schrieb:

    evilissimo schrieb:

    camper schrieb:

    die eingebauten operatoren && und || führen eine sog. kurzschlussauswertung aus: wenn das ergbenis durch den linken operanden bereits bestimmt ist, so wird der rechte operand nicht ausgewertet. das ist im übrigen der grund, warum diese operatoren nicht überladen werden sollten - denn ein überladener operantor ist eine normale funktion, die den üblichen regeln des funktions aufrufs unterliegt (alle operanden werden ausgewertet bevor die funktion aufgerufen wird), es ist nicht möglich, dieses kurzschlussverhalten für eigene operatoren zu erhalten.

    Hmm wo steht, dass das nicht geht? (Der Abschnitt würde mich mal interessieren)
    Ich glaube das nämlich nicht so ganz.

    Das folgt direkt aus der Tatsache, dass ein Operator immer durch eine *Funktion* überladen wird (siehe 13.5). Und die Regeln für Funktionen besagen, dass immer alle Argumente ausgewertet werden (wobei die Reihenfolge nicht spezifiziert ist).

    Hmm vielleicht reden wir hier an einander vorbei.

    Also das bei einem Funktionsaufruf erst einmal alles ausgewertet wird, ist mir ja klar.

    Also z.B:

    Foo(++a, b++, c++);
    

    Aber ich meine soetwas:

    #include <iostream>
    using namespace std;
    
    struct foo{
        foo():state(0){}
        foo & operator++(){
            cout << "Ausgefuehrt ++op" << endl;
            ++state;
            return *this;
        }
        foo operator++(int){
            cout << "Ausgefuehrt op++" << endl;
            foo tmp = *this;
            ++state;
            return tmp;
        }
        operator bool(){
            return state > 0;
        }
        unsigned get_state() const { return state; }
    private:
        unsigned state;
    };
    
    int main(){
        foo f;
        cout << "State: " << f.get_state() << endl;
        bool test = ++f || f++; // <<-- das
        cout << "State: " << f.get_state() << endl;
        return 0;
    }
    

    Wenn das so ist wie ihr sagt müsste die Ausgabe folgende sein:

    State: 0
    Ausgefuehrt ++op
    Ausgefuehrt op++
    State: 2

    Aber tatsächlich bekomme ich:

    State: 0
    Ausgefuehrt ++op
    State: 1

    Reden wir aneinander vorbei, oder ist der g++ da nicht Standardkonform?

    BR
    Vinzenz



  • Ich denke, die Standardkenner meinen die (potentielle) Überladung der Operatoren && und ||, und nichts anderes 😉



  • LordJaxom schrieb:

    Ich denke, die Standardkenner meinen die (potentielle) Überladung der Operatoren && und ||, und nichts anderes 😉

    Das kann sein *g* Das wurde irgendwie nur so verallgemeinert für Operatoren dargestellt das ich das nicht so aufgefasst habe.

    BR
    Vinzenz



  • LordJaxom schrieb:

    Ich denke, die Standardkenner meinen die (potentielle) Überladung der Operatoren && und ||, und nichts anderes 😉

    Genau die meinen wir.

    Nochmal in campers Beitrag reingeschaut (Hervorhebung von mir)

    camper schrieb:

    die eingebauten operatoren && und || führen eine sog. kurzschlussauswertung aus: wenn das ergbenis durch den linken operanden bereits bestimmt ist, so wird der rechte operand nicht ausgewertet. das ist im übrigen der grund, warum diese operatoren nicht überladen werden sollten[...]



  • Hmm... 😕

    Man kann doch auch eine eigene Funktion mit "Kurzschluss" beenden oder nicht?

    bool or( int a, int b ) {
        if( a )
            return true;     // Funktion wird beendet, wenn a != 0 ist
        if( b )
            return true;
        if( a && b )
            return true;
        return false;
    }
    

    Oder hab ich da was falsch verstanden?



  • Ja sicher, aber zum Zeitpunkt des Funktionsablaufs stehen a und b schon fest und sind damit vollständig ausgewertet.

    EDIT:

    a && a->x()
    

    vs.

    and(a, a->x())
    


  • aso...ja stimmt, schuldigung

    also sind dann bei

    or( a++, b++ );
    

    beide schon inkrementiert, richtig?



  • Richtig! Und das wäre bei den genannten Operatoren nicht das erwartete. Wenn ich z.B.

    KomplexerTyp *t = 0;
    if(t && t->funktion())
    

    würde ich nicht erwarten das versucht wird die Funktion aufzurufen (da der Pointer auf 0 gesetzt ist). Wenn das nun aber doch passiert, würde das Programm (vermutlich) wegknallen.


Anmelden zum Antworten