为什么 ++variable 在 C 中不被视为左值?
Why ++variable isn't treated as lvalue in C?
考虑以下 C 代码:
#include <stdio.h>
int main(void) {
int a = 0;
printf("%d\n", ++a += 1);
}
++
优先于 +=
所以应该首先计算它。所以我们在左边有 a
,在右边有 1
。现在根据我的理解 ++a
应该导致 a
(只改变它的值)这是左值所以为什么这个语句给出以下错误:
lvalue required as left operand of assignment
前缀增量运算符 ++
导致其操作数的增量值,但它不是左值。 C standard的第6.5.3.1p2节:语义描述如下:
The value of the operand of the prefix ++
operator is incremented.
The result is the new value of the operand after incrementation. The
expression ++E
is equivalent to (E+=1)
. See the discussions of
additive operators and compound assignment for information on
constraints, types, side effects, and conversions and the effects of
operations on pointers.
然后第 6.5.16.2p3 节关于复合赋值运算符指出:
A compound assignment of the form E1 op = E2
is equivalent to the
simple assignment expression E1 = E1 op (E2)
, except that the lvalue
E1
is evaluated only once, and with respect to an
indeterminately-sequenced function call, the operation of a compound
assignment is a single evaluation.
而 6.5.16p3 关于赋值运算符进一步指出:
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.
所以这是明确不允许的。即使是这样,像 ++a += 1
这样的表达式也会导致 a
在没有中间序列点的情况下被修改多次,这会触发未定义的行为。
这是 C 和 C++ 不同的地方之一。 C++ 实际上允许 =
运算符的结果,并通过扩展复合赋值和前缀 ++
/--
作为左值。
考虑以下 C 代码:
#include <stdio.h>
int main(void) {
int a = 0;
printf("%d\n", ++a += 1);
}
++
优先于 +=
所以应该首先计算它。所以我们在左边有 a
,在右边有 1
。现在根据我的理解 ++a
应该导致 a
(只改变它的值)这是左值所以为什么这个语句给出以下错误:
lvalue required as left operand of assignment
前缀增量运算符 ++
导致其操作数的增量值,但它不是左值。 C standard的第6.5.3.1p2节:语义描述如下:
The value of the operand of the prefix
++
operator is incremented. The result is the new value of the operand after incrementation. The expression++E
is equivalent to(E+=1)
. See the discussions of additive operators and compound assignment for information on constraints, types, side effects, and conversions and the effects of operations on pointers.
然后第 6.5.16.2p3 节关于复合赋值运算符指出:
A compound assignment of the form
E1 op = E2
is equivalent to the simple assignment expressionE1 = E1 op (E2)
, except that the lvalueE1
is evaluated only once, and with respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation.
而 6.5.16p3 关于赋值运算符进一步指出:
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.
所以这是明确不允许的。即使是这样,像 ++a += 1
这样的表达式也会导致 a
在没有中间序列点的情况下被修改多次,这会触发未定义的行为。
这是 C 和 C++ 不同的地方之一。 C++ 实际上允许 =
运算符的结果,并通过扩展复合赋值和前缀 ++
/--
作为左值。