Referenzen und konstante Referenzen



  • Hallo,

    in dem Buch (C++ Primer), dass ich gerade lese, steht

    double dvalue = 3.14159;
    
    // Nur für const-Referenzen zulässig
    const int &ir = 1024;
    const int &ir2 = dvalue;
    const double &dr = dvalue + 1.0;
    

    Die gleichen Initialisierungen sind für Referenzen, die nicht vom Typ const sind, nicht zulässig, sondern führen beim Kompilieren zu Fehlern.

    Wenn ich aber Folgendes bei mir kompiliere, kommt kein Fehler, es wird mir lediglich angezeigt, dass temporäre Objekte erzeugt werden (was ja soweit in Ordnung ist)

    double dvalue = 3.14159;
    
    int &ir = 1024;
    int &ir2 = dvalue;
    double &dr = dvalue + 1.0;
    

    Ist mein Compiler (Borland 5.5) in diesem Punkt nicht standardkonform oder ist das ein Fehler im Buch oder habe ich womöglich etwas falsch verstanden 😕 ?

    Gruß, Jens



  • Hallo,

    der Borland Kompiler verhaelt sich hier nicht Standardkonform. Hier zwar "nur"
    ein Auszug aus dem Draft, jedoch denke ich nicht, dass sich da grossartig was
    geaendert hat:

    8.3.2 References [dcl.ref]
    1 In a declaration T D where D has the form
    & D1
    and the type of the identifier in the declaration T D1 is "derived-
    declarator-type-list T," then the type of the identifier of D is
    "derived-declarator-type-list reference to T." Cv-qualified refer-
    ences are ill-formed except when the cv-qualifiers are introduced
    through the use of a typedef (_dcl.typedef_) or of a template type
    argument (_temp.arg_), in which case the cv-qualifiers are ignored.
    [Example: in
    typedef int& A;
    const A aref = 3; // ill-formed;
    // non-const reference initialized with rvalue
    the type of aref is "reference to int", not "const reference to int".
    ] [Note: a reference can be thought of as a name of an object. ] A
    declarator that specifies the type "reference to cv void" is ill-
    formed.

    Der gcc 3.3.1 verhaelt sich hier korrekt:

    int main() {
    	double dvalue = 3.14159;
    	int &ir = 1024;
    	int &ir2 = dvalue;
    	double &dr = dvalue + 1.0;
    
    		cout<<ir<<endl;
    
    	return 0;
    }
    

    Compilermessage:

    Compiling source file(s)...
    main.cpp
    main.cpp: In function int main()': main.cpp:7: error: could not convert \1024' to `int&'
    main.cpp:8: error: could not convert `dvalue' to `int&'
    main.cpp:9: error: could not convert (dvalue + 1.0e+0)' todouble&'
    main.cpp:8: warning: unused variable int&ir2' main.cpp:9: warning: unused variabledouble&dr'

    reference_test.exe - 3 error(s), 2 warning(s)

    Aendere ich das Programm aber folgendermassen ab, geht es durch den Kompiler:

    int main() {
    	double dvalue = 3.14159;
    	const int &ir = 1024;
    	const int &ir2 = dvalue;
    	const double &dr = dvalue + 1.0;
    
    		cout<<ir<<endl;
    
    	return 0;
    }
    

    Compiling source file(s)...
    main.cpp
    main.cpp: In function int main()': main.cpp:8: warning: argument to \int' from `double'
    main.cpp:8: warning: unused variable const int&ir2' main.cpp:9: warning: unused variableconst double&dr'
    Linking...

    reference_test.exe - 0 error(s), 3 warning(s)

    Es kommen zwar noch Warnung, welche allerdings leicht zu beseitigen sind.
    Mein Programm ist ja sehr minimal gehalten.

    Der Borland Kompiler haette hier also einen Fehler ausgeben muessen.

    mfg
    v R



  • double &dr = dvalue + 1.0;
    

    Ich glaube nicht, dass das kompilieren dürfte. Referenzen auf nicht-konstante Objekte dürfen nicht an temporäre Objekte gebunden werden. Das Ergebnis von dvalue + 1.0 ist so ein temporäres "Objekt". Es "lebt" nur bis zum Ende dieser Zeile - mit dr lässt sich danach nichts mehr anfangen.

    const double &dr = dvalue + 1.0;
    

    ist in Ordnung, da der Compiler hier dafür sorgt, dass das temporäre Objekt so lange lebt wie die Referenz dr.


Anmelden zum Antworten