Thread: lvalue rvalue discussion

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    1,579

    lvalue rvalue discussion

    Hello everyone,


    Just want to confirm and ask for advice here for experts, since I met with some confusions about recent reading.

    Here is my understanding,

    1. const reference is lvalue;
    2. non-const reference is lvalue;
    3. Return of constructor is rvalue.

    All correct?


    thanks in advance,
    George

  2. #2
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by George2 View Post
    Hello everyone,


    Just want to confirm and ask for advice here for experts, since I met with some confusions about recent reading.

    Here is my understanding,

    1. const reference is lvalue;
    2. non-const reference is lvalue;
    3. Return of constructor is rvalue.

    All correct?


    thanks in advance,
    George
    1. No
    2. Yes
    3. Constructors don't have return values.

    Someone else can elaborate, I'm outa time.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #3
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    I believe the return value from a constructor is an lvalue.
    Code:
    class T {};
    
    int main()
    {
    	T t;
    	T() = t;
    }

  4. #4
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks iMalc,


    1.

    Quote Originally Posted by iMalc View Post
    1. No
    Why reference to const is not a lvalue? I think the rule to judge lvalue and rvalue is whether or not it is addressable/nameable other than whether or no it could be on left side or right side of =.

    2.

    Quote Originally Posted by iMalc View Post
    3. Constructors don't have return values.
    I mean the object instance returned by contructor... Any comments?


    regards,
    George

  5. #5
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi bithub,


    In your below code, you invoke the assignment operator of the return value of T(), which is a rvalue. Any comments?

    Quote Originally Posted by bithub View Post
    I believe the return value from a constructor is an lvalue.
    Code:
    class T {};
    
    int main()
    {
    	T t;
    	T() = t;
    }

    regards,
    George

  6. #6
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    T() returns an lvalue which is demonstrated by it being on the left side of an assignment operation unless I am misunderstanding your question.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    1) Yes.
    2) Yes.
    3) Constructors don't have a return value. An explicit constructor expression has a value, though - the new object. Still an rvalue, though.

    However, there is a special rule that you can invoke member functions on temporary class objects, which converts the rvalue to an lvalue for the purpose of getting the this pointer. In particular, since
    T() = t;
    is equivalent to
    T().operator=(t);
    this rule applies. The expression T() still yields an rvalue (you couldn't apply & to it unless it's overloaded), but you can call a member function on it, and within the member, *this is an lvalue.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    No bithub,


    T() returns rvalue, please refer to CornedBee's reply in #7.

    Quote Originally Posted by bithub View Post
    T() returns an lvalue which is demonstrated by it being on the left side of an assignment operation unless I am misunderstanding your question.

    Thanks CornedBee,


    Why the following code can compile? Binding non-const reference to a temporary value by T()?

    My confusions are,

    1. I remembered non-const reference could only be binded to lvalue;
    2. Temporary value is rvalue, not lvalue.

    Code:
    class T {};
    
    int main()
    {
    	T& rt = T(); // why no compile error?
    
    	return 0;
    }

    Quote Originally Posted by CornedBee View Post
    1) Yes.
    2) Yes.
    3) Constructors don't have a return value. An explicit constructor expression has a value, though - the new object. Still an rvalue, though.

    However, there is a special rule that you can invoke member functions on temporary class objects, which converts the rvalue to an lvalue for the purpose of getting the this pointer. In particular, since
    T() = t;
    is equivalent to
    T().operator=(t);
    this rule applies. The expression T() still yields an rvalue (you couldn't apply & to it unless it's overloaded), but you can call a member function on it, and within the member, *this is an lvalue.

    regards,
    George
    Last edited by George2; 02-29-2008 at 04:16 AM.

  9. #9
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by George2 View Post
    Why reference to const is not a lvalue? I think the rule to judge lvalue and rvalue is whether or not it is addressable/nameable other than whether or no it could be on left side or right side of =.
    What you say is true. However, before the const keyword was introduced to C, an lvalue was defined as anything that could appear on the left hand side of an assignment. Since const was added to the language, that notion became a "modifiable lvalue".

    lvalues are values that have addresses, meaning they are variables or dereferenced references to a certain memory location. In other words, it designates (refers to, addresses, allows examination of) an object. A modifiable lvalue is both addressable and assignable. An unmodifiable lvalue is addressable, but not assignable.

    An rvalue is a value that is stored at a specific memory location (but not necessarily addressable). Any lvalue can be an rvalue (or implicitly converted to an rvalue -- meaning its value is fetched). However, not all rvalues are lvalues.

    The rvalue to lvalue conversion essentially allows assignment of the value of the rvalue into an lvalue.
    Last edited by grumpy; 02-29-2008 at 04:59 AM.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    T& rt = T();
    Another special case, the reasoning behind which I don't know. The rule is:
    If a reference is initialized with a temporary object, the lifetime of that temporary is extended to the lifetime of the reference.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by CornedBee View Post
    Another special case, the reasoning behind which I don't know. The rule is:
    If a reference is initialized with a temporary object, the lifetime of that temporary is extended to the lifetime of the reference.
    That rule only applies if it is a const reference. You can't extend the lifetime of a temporary by using a non-const reference.

    I was thinking of this, but as George reminds me, that is not the whole picture of what is an lvalue.:
    e.g.
    Code:
    int val = 42;
    int &ref = val;
    const int &cref = val;
    ref = 6; // fine
    cref = 7; // illegal
    Yes for #3 I knew what you meant George2, I was being pedantic
    Last edited by iMalc; 02-29-2008 at 01:42 PM.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    That rule only applies if it is a const reference.
    Compiler extension, then? If the code snippet compiles, somehow it must be supported.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Compiler extension, then?
    Maybe, this is an rvalue reference as expected to be in C++0x, right?

    If the code snippet compiles, somehow it must be supported.
    Which compiler did you use? As expected, it failed to compile with MSVC8 and the MinGW port of g++ 3.4.5.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Maybe, this is an rvalue reference as expected to be in C++0x, right?
    No, rvalue references use &&.

    Which compiler did you use? As expected, it failed to compile with MSVC8 and the MinGW port of g++ 3.4.5.
    I trusted George2's statement that he got no error. He's using VS 2008.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  15. #15
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi grumpy,


    Quote Originally Posted by grumpy View Post
    lvalues are values that have addresses, meaning they are variables or dereferenced references to a certain memory location. In other words, it designates (refers to, addresses, allows examination of) an object. A modifiable lvalue is both addressable and assignable. An unmodifiable lvalue is addressable, but not assignable.
    I do not understand what do you mean "dereferenced references", could you show some pseudo code please?

    BTW: I understand dereference and reference individually. I do not know what does it mean when you use the two term altogether. :-)


    Hi CornedBee,


    Yes, I am using Visual Studio 2008. I have some new findings and I want to share with you guys here. For the following code,

    Code:
    class Foo {
    };
    
    int main()
    {
    	Foo& rf = Foo();
    	return 0;
    }
    If I use warning level 4 (I use level 3 as default before), here are the new warning messages,

    --------------------
    1>d:\visual studio 2008\projects\test_reference3\test_reference3\main .cpp(6) : warning C4239: nonstandard extension used : 'initializing' : conversion from 'Foo' to 'Foo &'
    1> A non-const reference may only be bound to an lvalue
    1>d:\visual studio 2008\projects\test_reference3\test_reference3\main .cpp(6) : warning C4189: 'rf' : local variable is initialized but not referenced
    --------------------

    If I disable language extensions, compile error will be,

    --------------------
    1>d:\visual studio 2008\projects\test_reference3\test_reference3\main .cpp(6) : error C2440: 'initializing' : cannot convert from 'Foo' to 'Foo &'
    --------------------

    Quote Originally Posted by CornedBee View Post
    No, rvalue references use &&.


    I trusted George2's statement that he got no error. He's using VS 2008.

    regards,
    George

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. lvalue vs rvalue casting
    By fallout01 in forum C Programming
    Replies: 5
    Last Post: 07-12-2008, 02:35 AM
  2. Get lvalue through rvalue
    By George2 in forum C++ Programming
    Replies: 4
    Last Post: 12-17-2007, 08:53 AM
  3. Function argument not converted to reference
    By MWAAAHAAA in forum C++ Programming
    Replies: 14
    Last Post: 10-22-2006, 03:24 AM
  4. Question on l-values.
    By Hulag in forum C++ Programming
    Replies: 6
    Last Post: 10-13-2005, 04:33 PM
  5. Why wont my function exit correctly?
    By LightsOut06 in forum C Programming
    Replies: 2
    Last Post: 10-09-2005, 09:23 PM