下面的代码在 C 编译器中给出了编译错误
++(-i);
error: lvalue required as increment operand
这意味着 -i 返回右值。
而代码
++(+i);
不要给出任何错误。为什么这样?这个链接说 +i 不会产生左值。
这是您的编译器中的一个故障。在 C 语言中,表达式中的所有左值甚至在应用任何运算符之前都被转换为右值,除了sizeof
、&
、++
、--
和.
赋值的操作数(见 6.3.2/2)
换句话说,在 C 语言中+i
必须产生一个右值不是因为一元+
应该产生一个右值,而是因为在一元甚至有机会做它的事情之前i
被转换为右值。+
例如,对于int i
保存 value 的变量42
, expression+i
完全等效于 expression +42
。的左值性丢失了,并且在一元的语义发挥作用之前i
变成了左值性。42
+
不用说,在这种情况下,一元的结果+
不可能是左值。
来自 C99 标准(6.5.3.3 一元算术运算符):
2 一元 + 运算符的结果是其(提升的)操作数的值。整数提升在操作数上执行,结果具有提升的类型。
3 一元 - 运算符的结果是其(提升的)操作数的负数。整数提升在操作数上执行,结果具有提升的类型。
在这个特定的上下文中,没有代码会使用提升的值+i
,因此我相信你的编译器假设它等同于i
,因此将它视为左值。或者可能只是它根本没有实现一元+
。无论如何,这根本不是你应该做的事情,其他编译器会简单地禁止它。
-i
执行实际操作,因此其结果是临时的。因此,您不能增加它,因为它不再是变量。
该标准在6.3.2.1 其他操作数/左值、数组和函数指示符中明确了这一点:
2 除非它是 sizeof 运算符、一元 & 运算符、++ 运算符、-- 运算符或 . 的左操作数的操作数。运算符或赋值运算符,不具有数组类型的左值将转换为存储在指定对象中的值(并且不再是左值)。[…]