lvalue and rvalue?

Discussion in 'C Programming' started by Zach, Jan 10, 2009.

  1. Zach

    Zach Guest

    int x;
    x = 10;

    here x is the lvalue (the object holding a value) and 10 is the rvalue
    (the value being assigned to an object) correct?

    zach
     
    Zach, Jan 10, 2009
    #1
    1. Advertising

  2. Zach

    Magnus Brand Guest

    Zach wrote:
    > int x;
    > x = 10;
    >
    > here x is the lvalue (the object holding a value) and 10 is the rvalue
    > (the value being assigned to an object) correct?


    That's true. In K&R-2 it is stated that "An object is a named region of
    storage; an lvalue is an expression referring to an object". So in your
    example, 'x' is the expression and 10 the actual object.
    An exception to this are arrays, since the name of an array itself is an
    expression but can't be modified. So can refer to it as an "unmodofiable
    lvalue".

    Magnus
     
    Magnus Brand, Jan 10, 2009
    #2
    1. Advertising

  3. Zach <> writes:
    > int x;
    > x = 10;
    >
    > here x is the lvalue (the object holding a value) and 10 is the rvalue
    > (the value being assigned to an object) correct?


    The meanings of the terms "lvalue" and "rvalue" can be tricky.

    Before C existed, the terms "lvalue" and "rvalue" referred to two
    different ways of evaluating an expression. The 'l' and 'r' stand for
    "left" and "right", as in the left and right sides of an assignment
    statement. Evaluating an expression for its lvalue meant determining
    what object it designates. Evaluting an expression for its rvalue
    meant determining the value of the expression.

    For example, given the declaration "int x;" evaluating the expression
    ``x'' would mean determining the object to which it refers -- without
    accessing that object's value. In an exprssion like arr[func() + 3],
    this can involve more than just resolving a name. Evaluating the
    expression ``x'' for its rvalue would mean accessing the object to
    obtain the value stored in it. Some expressions, such as ``x + 1'',
    cannot be evaluated for their lvalues, because they don't refer to any
    object.

    The C standard changed the way the term "lvalue" is used, and almost
    entirely dropped the term "rvalue". In C, an "lvalue" is not the
    result of evaluating an expression, it's the expression itself. The
    only mention of "rlvalue" is in a footnote, which says that it just
    means the value of an expression. An expression that's not an lvalue
    isn't referred to as a rvalue; it's just a non-lvalue expression.

    An lvalue in C is basically an expression that designates an object.
    Just to add to the frivolity, the C89/C90 standard's definition of
    "lvalue" was worded incorrectly, and the C99 standard's revised
    definition attempted to correct it but just made a mess of the whole
    thing. (The mess is the result of trying to nail down case like *ptr,
    where ptr is a pointer that doesn't currently point to an object.
    *ptr is still an lvalue, but trying to use it as one invokes undefined
    behavior. In two attempts, the standard has failed to express that
    correctly.)

    So in your statement:
    x = 10;
    the subexpression x is an lvalue, and is used as an lvalue, because it
    designates the object named "x".

    Given:

    int x;
    int y = 10;
    x = y;

    In the assignment, both subexpressions x and y are lvalues, because
    they're both expressions that designate objects. But y is not being
    used as an lvalue; it's in a context, the right hand side of an
    assignment, that doesn't require an lvalue. So the fact that it's an
    lvalue is incidental. The left side of an assignment is a context
    that does require an lvalue, so this:

    (x + 1) = y;

    is illegal (a constraint violation).

    Sorry to have to give such a long explanation, but your question
    wasn't as simple as it appeared (or as it should be).

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 10, 2009
    #3
  4. Magnus Brand <> writes:
    > Zach wrote:
    >> int x;
    >> x = 10;
    >> here x is the lvalue (the object holding a value) and 10 is the
    >> rvalue
    >> (the value being assigned to an object) correct?

    >
    > That's true. In K&R-2 it is stated that "An object is a named region
    > of storage; an lvalue is an expression referring to an object".


    So x is an lvalue, but an lvalue is an expression, not an object.

    > So in
    > your example, 'x' is the expression and 10 the actual object.


    'x', '10', and 'x = 10' are all expressions. 10 is not an object.

    > An exception to this are arrays, since the name of an array itself is
    > an expression but can't be modified. So can refer to it as an
    > "unmodofiable lvalue".


    Right, an array name is an unmodifiable lvalue. (An array *object* is
    not an lvalue; it's an object.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 10, 2009
    #4
  5. Zach

    Magnus Brand Guest

    Keith Thompson wrote:
    > So x is an lvalue, but an lvalue is an expression, not an object.
    > 10 is not an object.

    I never said an lvalue was an object.
    But why isn't '10' an object? I thought a data object was just a region
    in memory that contains one value (or several values). So you've got a,
    e.g. 4 bytes long memory section that holds this value.

    I bid for rectification.

    Magnus
     
    Magnus Brand, Jan 11, 2009
    #5
  6. Magnus Brand <> writes:
    > Keith Thompson wrote:
    >> So x is an lvalue, but an lvalue is an expression, not an object.
    >> 10 is not an object.

    > I never said an lvalue was an object.


    The original poster more or less did:

    here x is the lvalue (the object holding a value)

    > But why isn't '10' an object? I thought a data object was just a
    > region in memory that contains one value (or several values). So
    > you've got a, e.g. 4 bytes long memory section that holds this value.


    Objects have addresses.

    The context was an assignment:

    x = 10;

    An "object" is, by definition, a "region of data storage in the
    execution environment, the contents of which can represent values".
    10 is a value, not an object. It's not necessarily stored in memory.
    In particular, it has no address.

    An implementation might choose to store it in memory, but that's an
    implementation detail that doesn't affect the question of whether it
    can formally be considered to be an object. For example, the CPU
    might have a "store ten in specified location" instruction.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 11, 2009
    #6
  7. Zach

    James Kuyper Guest

    Magnus Brand wrote:
    > Keith Thompson wrote:
    > > So x is an lvalue, but an lvalue is an expression, not an object.
    > > 10 is not an object.

    > I never said an lvalue was an object.
    > But why isn't '10' an object? I thought a data object was just a region
    > in memory that contains one value (or several values). So you've got a,
    > e.g. 4 bytes long memory section that holds this value.


    The key point is that use of the integer literal 10 does not actually
    require that a piece of memory be set aside to store a value of 10. If
    you write 10*x, an implementation could just build that value (directly
    or indirectly) into the executable code that performs the multiplication.

    For instance, I've heard that there are some implementations which might
    (under the right circumstances) generate code for 10*x which would be
    equivalent to 8*x+2*x, or in other words, x<<3 + x<<1. On the hardware
    these implementations were intended for, the two shifts and the addition
    execute faster than the multiply, and the equivalent of the '3' and the
    '1' are stored directly as part of the shift instruction. Its been so
    long since I heard this that I can't remember what the target hardware
    was; and it's quite possible that there are no longer any machines where
    this would be a good idea; but that's irrelevant to my point. Even if
    there were no such implementation, it would still be the case that such
    an implementation would be perfectly conforming, and that IS my point.
     
    James Kuyper, Jan 11, 2009
    #7
  8. Zach

    Ian Collins Guest

    Magnus Brand wrote:
    > Keith Thompson wrote:
    >> So x is an lvalue, but an lvalue is an expression, not an object.
    >> 10 is not an object.

    > I never said an lvalue was an object.
    > But why isn't '10' an object? I thought a data object was just a region
    > in memory that contains one value (or several values). So you've got a,
    > e.g. 4 bytes long memory section that holds this value.
    >

    In addition to Keith's points, how do you propose assigning a value to '10'?

    --
    Ian Collins
     
    Ian Collins, Jan 11, 2009
    #8
  9. James Kuyper wrote:
    > For instance, I've heard that there are some implementations which might
    > (under the right circumstances) generate code for 10*x which would be
    > equivalent to 8*x+2*x, or in other words, x<<3 + x<<1. On the hardware
    > these implementations were intended for, the two shifts and the addition
    > execute faster than the multiply, and the equivalent of the '3' and the
    > '1' are stored directly as part of the shift instruction. Its been so
    > long since I heard this that I can't remember what the target hardware
    > was; and it's quite possible that there are no longer any machines where
    > this would be a good idea; but that's irrelevant to my point. Even if
    > there were no such implementation, it would still be the case that such
    > an implementation would be perfectly conforming, and that IS my point.


    Actually, turning multiplication and division by a constant into
    shifting, addition, and/or subtraction is a very common optimization, or
    at least the base of one.

    For example, GCC turns "y = x * 10" into the following on my machine:

    y = x;
    y <<= 2;
    y += x;
    y += y;

    That's pretty clever for "no" optimization. If I turn it up a notch:

    y = x*4 + x;
    y += y;

    (x86's LEA instruction can do a*b+c iff b is a constant power of two.
    It's really a fused shift-add instruction, not a fused multiply-add, but
    convention is to write it as a multiply-add.)

    S

    --
    Stephen Sprunk "Stupid people surround themselves with smart
    CCIE #3723 people. Smart people surround themselves with
    K5SSS smart people who disagree with them." --Isaac Jaffe
     
    Stephen Sprunk, Jan 11, 2009
    #9
  10. Zach

    Magnus Brand Guest

    Ian Collins wrote:
    > In addition to Keith's points, how do you propose assigning a value to '10'?

    You can't because as a it's always an rvalue, I'd say. Assignments are
    the reason why lvalues exist.

    Magnus
     
    Magnus Brand, Jan 11, 2009
    #10
  11. Zach

    Phil Carmody Guest

    Keith Thompson <> writes:
    > Magnus Brand <> writes:
    >> Keith Thompson wrote:
    >>> So x is an lvalue, but an lvalue is an expression, not an object.
    >>> 10 is not an object.

    >> I never said an lvalue was an object.

    >
    > The original poster more or less did:
    >
    > here x is the lvalue (the object holding a value)
    >
    >> But why isn't '10' an object? I thought a data object was just a
    >> region in memory that contains one value (or several values). So
    >> you've got a, e.g. 4 bytes long memory section that holds this value.

    >
    > Objects have addresses.
    >
    > The context was an assignment:
    >
    > x = 10;
    >
    > An "object" is, by definition, a "region of data storage in the
    > execution environment, the contents of which can represent values".
    > 10 is a value, not an object. It's not necessarily stored in memory.
    > In particular, it has no address.


    But c.f.
    register int x=10; /* x also isn't /necessarily/ stored in memory */

    However that example doesn't contradict the quoted definition in any way.

    > An implementation might choose to store it in memory, but that's an
    > implementation detail that doesn't affect the question of whether it
    > can formally be considered to be an object. For example, the CPU
    > might have a "store ten in specified location" instruction.


    And in fact some of the less brain-dead architectures I've
    worked with do.

    Phil
    --
    I tried the Vista speech recognition by running the tutorial. I was
    amazed, it was awesome, recognised every word I said. Then I said the
    wrong word ... and it typed the right one. It was actually just
    detecting a sound and printing the expected word! -- pbhj on /.
     
    Phil Carmody, Jan 11, 2009
    #11
  12. Phil Carmody <> writes:
    > Keith Thompson <> writes:

    [...]
    >> Objects have addresses.

    [...]
    >>
    >> The context was an assignment:
    >>
    >> x = 10;
    >>
    >> An "object" is, by definition, a "region of data storage in the
    >> execution environment, the contents of which can represent values".
    >> 10 is a value, not an object. It's not necessarily stored in memory.
    >> In particular, it has no address.

    >
    > But c.f.
    > register int x=10; /* x also isn't /necessarily/ stored in memory */
    >
    > However that example doesn't contradict the quoted definition in any way.


    Good point. My statement that "Objects have addresses." was an
    over-generalization. Bit fields are another exception.

    "data storage" is not necessarily addressible memory.

    [...]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 11, 2009
    #12
  13. Zach

    CBFalconer Guest

    James Kuyper wrote:
    >

    .... snip ...
    >
    > For instance, I've heard that there are some implementations which
    > might (under the right circumstances) generate code for 10*x which
    > would be equivalent to 8*x+2*x, or in other words, x<<3 + x<<1. On
    > the hardware these implementations were intended for, the two
    > shifts and the addition execute faster than the multiply, and the
    > equivalent of the '3' and the '1' are stored directly as part of
    > the shift instruction. ...


    That's just a means of implementing the multiply. The basic
    requirements, to ensure it is worthwhile, is that one of the
    operands is a constant, and that that operand can be represented as
    the sum or difference of two binary powers. For example, if the
    constant in binary is 0000011100 that can be represented by (32 *
    OP2) - (4 * OP2), and the 32 and 4 are achieved by shifting.
    Similarly 0001000010 is represented by (2 * OP2) + (64 * OP2).
    Very useful when the machinery has no multiply instruction, and a
    routine must be called. To keep the number of shifts down, just
    insist the multiplier is less than some suitable constant before
    generating that code.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Jan 12, 2009
    #13
  14. Zach

    Kaz Kylheku Guest

    On 2009-01-11, Magnus Brand <> wrote:
    > Ian Collins wrote:
    >> In addition to Keith's points, how do you propose assigning a value to '10'?

    > You can't because as a it's always an rvalue, I'd say. Assignments are
    > the reason why lvalues exist.


    You can use lvalues to access objects. Or to take the address which is later
    used perhaps only for accessing, and not modifying.

    Lvalues don't even have to be modifiable, and only the modifiable ones
    can be assigned to.

    An expression that designates an array is an lvalue. Does that exist
    for the sake of assigning to an array?
     
    Kaz Kylheku, Jan 12, 2009
    #14
  15. Zach

    Kaz Kylheku Guest

    On 2009-01-11, Han from China - Master Troll <>
    wrote:
    > Keith Thompson wrote:
    >> Objects have addresses.

    >
    > I don't recommend that the OP listen to Keith Thompson. He's had
    > a habit in recent days of making erroneous statements. Or maybe it's
    > just that I've decided to start pointing them out.
    >
    > If objects are guaranteed addresses, then the standard wouldn't take
    > pains to use the phrase "non-bitfield objects".


    You're looking too hard. Your points are easily supported by the
    definitions section.

    > take pains to make certain exceptions for objects declared with the
    > storage-class specifier 'register'.


    3.5 bit: unit of data storage in the execution environment large enough
    to hold an object that may have one of two values.

    3.14 object: region of data storage in the execution environment,
    the contents of which can represent values.

    I seem to recall C90 objects being addressable by definition, but that's
    clearly not the case now.
     
    Kaz Kylheku, Jan 12, 2009
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mark Stijnman
    Replies:
    2
    Views:
    481
    =?ISO-8859-15?Q?Juli=E1n?= Albo
    Apr 22, 2005
  2. Kavya
    Replies:
    9
    Views:
    513
    Dik T. Winter
    Oct 28, 2006
  3. jimjim

    lvalue (s) and rvalue (s)

    jimjim, Mar 25, 2006, in forum: C++
    Replies:
    7
    Views:
    397
    Kai-Uwe Bux
    Mar 26, 2006
  4. Lighter
    Replies:
    6
    Views:
    422
    Lighter
    Jun 21, 2007
  5. Juha Nieminen
    Replies:
    13
    Views:
    620
    Edek Pienkowski
    Aug 29, 2012
Loading...

Share This Page