Unerwünschte Schlauheit vom Compiler



  • Hallo zusammen,

    Folgendes kleines Programm:

    int& fkt(int& a){
    return a;
    }

    int main(){
    int x = 5000;
    cout << fkt(x) << endl;
    return 0;
    }

    Nach der Ausführung der Funktion hat x wie erwartet den Wert 5000. Das "Ergebnis" von fkt(x) ist also eine Zahl.

    Nun eine kleine Veränderung im main-Rumpf:

    int& fkt(int& a){
    return a;
    }

    int main(){
    int x = 5000;
    fkt(x) = 1;
    cout << x << endl;
    return 0;
    }

    Hier erfolgt eine Zuweisung von 1 an a, und somit an x, da a ja eine Referenz von x ist.

    Im ersten Fall spuckt fkt(x) eine Zahl raus, nämlich 5000.
    Im zweiten Fall "erlaubt" der Compiler die Betrachtung von fkt(x) weiterhin als Referenz von x, deshalb konnte die Zuweisung problemlos erfolgen.

    Mir weist dies aber eine gewisse Unkonsistenz vom Compiler. Ich hätte gewünscht, dass der 2. Fall einen Fehler fabrizieren würde, da 5000 ≠ 1.
    Also, mir kommts so vor, als der Compiler so schlau ist und guckt erstmal wofür das Ergebnis der Funktion verwendet wird, je nachdem macht er dann diese Anpassung.

    Oder liegt da ein Denkfehler meinerseits? Ich bedanke mich für jegliche Hilfestellung.

    Grüße aus dem Rheinland,

    Leon



  • Das ist vollkommen richtiges Verhalten.

    Ich hätte gewünscht, dass der 2. Fall einen Fehler fabrizieren würde, da 5000 ≠ 1.

    Warum? ftk(x) gibt einfach eine Referenz auf x zurück, d.h. fkt(x) IST x. Wenn du jetzt eine Zuweisung durchführst (fkt(x) = 1;), dann ist x nachher eben 1.



  • Mir weist dies aber eine gewisse Unkonsistenz vom Compiler. Ich hätte gewünscht, dass der 2. Fall einen Fehler fabrizieren würde, da 5000 ≠ 1.

    Den Fehler kriegst du auch, wenn du ein == statt = verwendest.
    Ansonsten, wenn du die zurückgegebene Referenz nur als R-Value verwenden möchtest, mach sie const.

    const int &fkt(int &a)
    {
        return a;
    }
    


  • gogalop23 schrieb:

    Das "Ergebnis" von fkt(x) ist also eine Zahl.

    Das "Ergebnis" von fkt(x) ist keine Zahl, sondern eine Referenz auf ein int -Objekt, welches irgend eine Zahl speichert.

    gogalop23 schrieb:

    Mir weist dies aber eine gewisse Unkonsistenz vom Compiler.

    Wo siehst Du hier eine Inkonsistenz?

    gogalop23 schrieb:

    Ich hätte gewünscht, dass der 2. Fall einen Fehler fabrizieren würde, da 5000 ≠ 1.

    Was hat das eine mit dem anderen zu tun?

    gogalop23 schrieb:

    Also, mir kommts so vor, als der Compiler so schlau ist und guckt erstmal wofür das Ergebnis der Funktion verwendet wird, ...

    Hier passiert nichts besonderes. Klappt alles so, wie es soll. Wenn Du die Funktion eine "Zahl" zurückgeben lassen willst, musst Du int statt int& als Rückgabetyp verwenden.



  • Das ist keine Inkosistenz im Compiler, sondern eher inkonsistente Benutzung von Referenzen deinerseits. Der Compiler verhält sich da genau so wie der Standard es vorschreibt.



  • Vielleicht solltest Du Dir mal eine deklarativ-funktionale Sprache wie z.B. Prolog ansehen. Dort werden Variablen wie von Dir erwartet bei der Deklaration an einen Wert gebunden.
    In imperativen Sprachen wie C++ ist das hingegen anders.



  • Ich glaube dem OP ist einfach nicht klar wie Referenzen in C++ zu verstehen sind, und wann und wo die Umwandlung einer Lvalue in eine Rvalue erfolgt, bzw. was das überhaupt ist.

    Ist ja auch nicht ganz einfach zu verstehen/erklären.


Anmelden zum Antworten