Question

test.(c/cpp)

#include <stdio.h>

int main(int argc, char** argv)
{
  int a = 0, b = 0;
  printf("a = %d, b = %d\n", a, b);
  b = (++a)--;
  printf("a = %d, b = %d\n", a, b);

  return 0;
}

If I save the above as a .cpp file, it compiles and outputs this upon execution:

a = 0, b = 0
a = 0, b = 1

However, if I save it as a .c file, I get the following error:

test.c:7:12: error: lvalue required as decrement operator.

Shouldn't the (++a) operation be resolved before the (newValue)-- operation? Does anyone have any insight on this?

Was it helpful?

Solution

In C the result of the prefix and postfix increment/decrement operators is not an lvalue.

In C++ the result of the postfix increment/decrement operator is also not an lvalue but the result of the prefix increment/decrement operator is an lvalue.

Now doing something like (++a)-- in C++ is undefined behavior because you are modifying an object value twice between two sequence points.

EDIT: following up on @bames53 comment. It is undefined behavior in C++98/C++03 but the changes in C++11 on the idea of sequence points now makes this expression defined.

OTHER TIPS

In C and C++, there are lvalue expressions which may be used on the left-hand side of the = operator and rvalue expressions which may not. C++ allows more things to be lvalues because it supports reference semantics.

++ a = 3; /* makes sense in C++ but not in C. */

The increment and decrement operators are similar to assignment, since they modify their argument.

In C++03, (++a)-- would cause undefined behavior because two operations which are not sequenced with respect to each other are modifying the same variable. (Even though one is "pre" and one is "post", they are unsequenced because there is no ,, &&, ?, or such.)

In C++11, the expression now does what you would expect. But C11 does not change any such rules, it's a syntax error.

For anybody who might want the precise details of the differences as they're stated in the standards, C99, §6.5.3/2 says:

The value of the operand of the prefix ++ operator is incremented. The result is the new value of the operand after incrementation.

By contrast, C++11, §5.3.2/1 says:

The result is the updated operand; it is an lvalue, and it is a bit-field if the operand is a bit-field.

[emphasis added, in both cases]

Also note that although (++a)-- gives undefined behavior (at least in C++03) when a is an int, if a is some user-defined type, so you're using your own overloads of ++ and --, the behavior will be defined -- in such a case, you're getting the equivalent of:

a.operator++().operator--(0);

Since each operator results in a function call (which can't overlap) you actually do have sequence points to force defined behavior (note that I'm not recommending its use, only noting that the behavior is actually defined in this case).

§5.2.7 Increment and decrement:

The value of a postfix ++ expression is the value of its operand. [ ... ]  The operand shall be a modifiable lvalue.

The error you get in your C compilation helps to suggest that this is only a feature present in C++.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top