让我们考虑以下代码:
int main() {
int i = 2;
int b = ++i++;
return 3;
}
它会与以下内容一起编译,并显示错误:
<source>: In function 'int main()':
<source>:3:16: error: lvalue required as increment operand
3 | int b = ++i++;
| ^~
这对我来说听起来很公平。后缀递增的优先级高于前缀递增的优先级,因此将代码解析为int b = ++(i++);
,而i
是右值。因此是错误。
现在让我们考虑带有括号的此变体,以覆盖默认优先级:
int main() {
int i = 2;
int b = (++i)++;
return 3;
}
此代码编译并返回3。就我而言,这听起来很公平,但似乎与第一个代码矛盾。
问题:为什么(++i)
不是lvalue
时,i
是<source>:3:13: error: expression is not assignable
int b = ++i++;
^ ~~~
?
谢谢!
更新:上面显示的错误消息来自gcc(x86-64 9.2)。这是确切的渲染: error with gcc
Clang x86-64 9.0.0具有完全不同的消息: error with clang
++i
使用GCC,您会发现问题出在postfix运算符上,然后您就可以绕开为什么i
可以而SELECT * FROM `wp_postmeta` WHERE `meta_key` = '_stock_status'
不好的原因,因此是我的问题。使用Clang可以清楚地知道问题出在前缀运算符上。
答案 0 :(得分:23)
i
和++i
都是左值,而i++
是右值。
++(i++)
无效,因为将前缀++
应用于右值i++
。但是(++i)++
很好,因为++i
是左值。
请注意,在C中,情况有所不同; i++
和++i
都是右值。 (这是为什么人们应该停止假设C和C ++具有相同规则的示例。人们将这些假设插入他们的问题中,然后必须予以驳斥。)
答案 1 :(得分:4)
此声明
int b = ++i++;
等同于
int b = ++( i++ );
后缀增量运算符返回增量之前操作数的值。
根据C ++ 17标准(8.2.6递增和递减)
1后缀++表达式的值是其后缀++的值 操作数... 结果是prvalue 。
一元增量运算符在其增量后返回左值。所以这个声明
int b = (++i)++;
有效。例如,您可以写
int b = (++++++++i)++;
根据C ++ 17标准(8.3.2递增和递减)
1前缀++的操作数通过加1进行修改。操作数应为 是可修改的左值。操作数的类型应为算术 cv bool以外的其他类型,或指向完全定义的对象的指针 类型。 结果是更新的操作数;这是左值,并且是 如果操作数是位字段,则为位字段。...
请注意,在C中,两个运算符都返回一个值而不是左值。所以在C中这个声明
int b = (++i)++;
无效。
答案 2 :(得分:3)
因此代码被解析为int b = ++(i ++);我是右值。
不。 i
不是右值。 i
是左值。 i++
是一个右值(具体来说是右值)。