Why are multiple increments/decrements valid in C++ but not in C?

我怕爱的太早我们不能终老 提交于 2019-12-01 16:24:15

问题


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?


回答1:


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.




回答2:


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.




回答3:


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).




回答4:


§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++.



来源:https://stackoverflow.com/questions/14798953/why-are-multiple-increments-decrements-valid-in-c-but-not-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!