2

I am trying to run a part of code and had to increment the value of a combined expression a+b. In trying to do this I wrote the statement

c=(a+b)++

Getting following error on this statement-
"expression must be a modifiable value"

Why am I getting this error and why is incrementing the value of an expression not allowed in C?

H.S.
  • 11,654
  • 2
  • 15
  • 32

6 Answers6

4

In C, the operand of ++ must be an lvalue - a location in the memory. Both a and b are lvalues - but their sum is not, it is an rvalue.

DYZ
  • 55,249
  • 10
  • 64
  • 93
3

The postincrement operator can only be applied to an l-value, i.e. something that can appear to the left of the assignment operator, most commonly a variable.

When x++ appears in an expression it is evaluated as x and x is increased afterward. For example a = 2; b = 2 * (a++); is equivalent to a = 2; b = 2 * a; a = a + 1;.

Your example fails to compile because it is not possible to assign a value to a+b. To be more explicit c=(a+b)++ would be equivalent to c = (a + b); (a + b) = (a + b) + 1;, which makes no sense.

2

Because the ++ operator need a reference (l-value), not a value (r-value).

i++ will increase i by 1 and return value of i before increasing.

while (a + b)++ can't increase value of (a + b) since (a + b) is not actually a reference (in memory, where to update value of a + b).

Daniel Tran
  • 6,083
  • 12
  • 25
2

C11 6.5.3.1p1:

  1. The operand of the prefix increment or decrement operator shall have atomic, qualified, or unqualified real or pointer type, and shall be a modifiable lvalue.

What this means is that if we have a construct something ++, then something

  • must be real: integral or floating point, but cannot be a complex number
  • or can be of a pointer type (but a void pointer does not do because it does not have arithmetic defined)
  • it can be also _Atomic or volatile
  • but it must be an lvalue, i.e. designate an object that is modified by the increment
  • and that lvalue must be modifiable (for example it cannot be const qualified)

The expression

a + b

is not an lvalue expression, it does not designate an object. It is an arithmetic expression; and the value of an arithmetic expression is not an lvalue. While you can add 1 to that value, the value of an expression is not an object to modify.


However, given

int a, *b, c[5][6];
struct FOO { char *bar; } foo, *fooz;
double *funnyfunc(int x);

all these expressions are modifiable scalar lvalues:

a
*(b + 5)
c[1][4]
foo.bar
fooz->bar
funnyfunc(5)[42]

and you can apply ++ to them.


There is one more problem with

c = (a + b) ++

the value of the post-increment expression is the value before increment, i.e. even if that a + b were modifiable, c would not have value a + b + 1 but a + b anyway; and the a + b would change its stored value for subsequent evaluations.

1

There is come confusion about the meaning of increment. In your problem, you are supposed to add one to the expression a + b, which can be described as compute the sum of a and b and increment by one. In C the increment operator ++ has very specific semantics: it increments the value of a scalar variable as a side effect and evaluates either to the incremented value or to the original value depending on whether it is placed before or after said variable. Further restrictions apply, regarding the type of the object, and the use of the same object elsewhere in the same expression.

For your problem, the solution is to add 1 with the addition operator: a + b + 1

chqrlie
  • 131,814
  • 10
  • 121
  • 189
0

an easy to remember statement is

LValue - Left Value

LValue must be a container. In other words a memory location that can store something and is not restricted to do so And, variables are the only containers available in C.

in the example (a + b)++

(a + b) evaluates to some value and not necessarily that is a container that can be used again to operate on top of.

for instance consider this

const int a=10; 
a = 5;

similar error will be raised here, even though a here is a container, it is not useful because its a constant and no other operation this is permitted.

asio_guy
  • 3,667
  • 2
  • 19
  • 35