aal*_*vic 3 c++ compiler-construction standards
Why is the first expression allowed, but the second not:
void test()
{
int a;
++a = getSomeInt();
a++ = getSomeInt();
}
Run Code Online (Sandbox Code Playgroud)
I mean, why its forbidden for the second one to be an lvalue? The second one makes sense and the first not. In the first one we increment the variable and immediately after we gave here a new value, we lose it. That's not the case in the second expression. It makes sense to assign some value and increment the variable after that.
后缀增量的结果是prvalue,它表示纯rvalue,因此它不可修改.这是根据后缀表达式部分中的C++标准草案增量和减量表示(强调我的):5.2.6
后缀++表达式的值是其操作数的值.[注意:获得的值是原始值的副本 -end note] [...] 结果是prvalue.[...]
如果你考虑它,这是有道理的,因为你需要返回它的先前值a必须是一个临时值.
为了完整起见,增量和减量部分中的前缀增量语言表示(强调我的):5.3.2
前缀++的操作数通过添加1来修改,或者如果它是bool则设置为true(不推荐使用此用法).操作数应是可修改的左值.操作数的类型应为算术类型或指向完全定义的对象类型的指针.结果是更新的操作数; 这是一个左值 [...]
更新
我意识到:
++a = getSomeInt();
Run Code Online (Sandbox Code Playgroud)
在C++ 03中调用未定义的行为,我们可以看到,通过查看较旧的草案标准中的相关部分,将是第4段表达式:5
[...] 在前一个和下一个序列点之间,标量对象的表达式评估最多只能修改一次存储值.此外,只能访问先前值以确定要存储的值.对于完整表达式的子表达式的每个允许排序,应满足本段的要求; 否则行为未定义.
所以,因为你不止一次修改 a它是未定义的.据我所知,这在C++ 11中得到了很好的定义,在1.9 程序执行第15段中说:
除非另有说明,否则对单个运算符的操作数和单个表达式的子表达式的评估是不确定的.[...] 如果标量对象的副作用相对于同一标量对象的另一个副作用或使用相同标量对象的值的计算值未被排序,则行为未定义.
我们可以在5.17 Assignment和复合赋值运算符第1节中看到:
[...]在所有情况下,赋值在右和左操作数的值计算之后,以及赋值表达式的值计算之前排序.[...]
但无论如何,即使它是如此明确定义的表达式:
++a = getSomeInt();
Run Code Online (Sandbox Code Playgroud)
难以阅读和维护,应该避免使用更简单的代码.
更新2
不确定我是如何错过这个但是你没有a在这里初始化:
int a;
Run Code Online (Sandbox Code Playgroud)
所以它会有一个不确定的值,我们不知道它的初始值将是与执行预增量上a也将是不确定的行为.