Search code examples
cassignment-operatorevaluation

What's the point of evaluating left operand of assignment operator in C?


According to ISO C11 - 6.5.16.3, it says that

  1. An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue. The type of an assignment expression is the type the left operand would have after lvalue conversion. The side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands. The evaluations of the operands are unsequenced.

So I guess this means that, for example,

int x = 10;
x = 5 + 10;
  1. Left operand x is evaluated to 10 and right operand is evaluated to 15.
  2. Right operand value is stored in the object designated by the left operand x.

But if the purpose of the assignment is to store the evalauted value of right operand(just like in step2), why is evaluation of left operand necessary? What's the point of evaluating the left operand?


Solution

  • When x is evaluated as an lvalue, it does not evaluate to 10. It evaluates to an lvalue where the value of the RHS can be stored. If the LHS does not evaluate to an lvalue, the statement would be an error.

    From the C99 Standard (6.3.2.1/1):

    An lvalue is an expression (with an object type other than void) that potentially designates an object; if an lvalue does not designate an object when it is evaluated, the behavior is undefined.

    The evaluation of the LHS as an lvalue is trivial when you have a simple variable, such as

     x = 10;
    

    However, it can be more complex.

     double array[10];
     int getIndex();   // Some function that can return an index based
                       // on other data and logic.
    
     array[getIndex()+1] = 10.0;
    
     // This looks like a function call that returns a value.
     // But, it still evaluates to a "storage area".
     int *getIndex2() { return(&array[0]); }
     *getIndex2()=123.45; // array[0]=123.45
    

    If getIndex() returns 5, then the LHS evaluates to an lvalue that designates the 7-th element of the array.