前缀和后缀运算符的怪异行为 [英] Weird behaviour of prefix and postfix operators

查看:101
本文介绍了前缀和后缀运算符的怪异行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么允许第一个表达式,但不允许第二个表达式:

Why is the first expression allowed, but the second not:

void test()
{
   int a;

   ++a = getSomeInt();
   a++ = getSomeInt();
}

我的意思是,为什么它禁止第二个成为左值?第二个有意义,第一个没有意义。在第一个变量中,我们增加变量,在给定新值之后,我们立即丢失它。第二个表达式不是这种情况。分配一些值并在此之后增加变量是有意义的。

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 ,表示纯右值,因此该值不可修改。这是根据草稿C ++标准后缀表达式部分的 5.2.6 递增和递减中,其中说(强调我的) :

The result of postfix increment is prvalue which mean pure rvalue so it is not modifiable. This is per the draft C++ standard under postfix expressions section 5.2.6 Increment and decrement which says (emphasis mine):


后缀++表达式的值是其操作数的值。 [注意:获得的值是原始值的副本 —尾注] [...] 结果是prvalue 。 [...]

The value of a postfix ++ expression is the value of its operand. [ Note: the value obtained is a copy of the original value —end note ] [...] The result is a prvalue. [...]

这点很有意义,因为您需要返回以前的 a 它必须是一个临时值。

this makes sense if you think about it, since you need to return the previous value of a it has to be a temporary value.

为完整起见, 5.3.2 c部分的前缀增量语言 >递增和递减说(强调我的):

For completeness sake the language for prefix increment in section 5.3.2 Increment and decrement says (emphasis mine):


前缀++的操作数为通过加1进行修改,如果为bool,则将其设置为true(不建议使用此用法)。 操作数应为可修改的左值。操作数的类型应为算术类型或指向完全定义的对象类型的指针。 结果是更新的操作数;这是左值 [...]

The operand of prefix ++ is modified by adding 1, or set to true if it is bool (this use is deprecated). The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer to a completely-defined object type. The result is the updated operand; it is an lvalue [...]

更新

我意识到:

++a = getSomeInt();

调用 C ++ 03 中,= nofollow>未定义的行为,我们可以通过查看旧标准草案将是 5 表达式段落 4 其中说:

invokes undefined behavior in C++03, we can see that by looking at the relevant section in an older draft standard would be section 5 Expressions paragraph 4 which says:


[...] 标量对象的上一个和下一个序列点必须通过表达式的计算最多一次修改其存储值。此外,应仅访问先验值以确定要存储的值。对于完整表达式的子表达式的每个允许的排序,都应满足本段的要求; 否则行为是不确定的。

[...]Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.

因此,由于您正在修改 a 多次被未定义。据我所知,这在 C ++ 11 中有很好的定义,该部分在 1.9 程序执行段落 15 说:

so since you are modifying a more than once it is undefined. As far as I can tell this is well defined in C++11 which in section 1.9 Program execution paragraph 15 says:


除非特别指出,否则对单个运算符的操作数和单个表达式的子表达式的求值是无序列的。 [...] 如果相对于相同标量对象上的另一个副作用或使用相同标量对象的值进行的值计算,相对于一个标量对象的副作用未排序,则该行为是不确定的。

,我们可以在 5.17 部分看到赋值运算符 1 段说:

and we can see in section 5.17 Assignment and compound assignment operators paragraph 1 says:


[...]在所有情况下,赋值在左右操作数的值计算之后和赋值表达式的值计算之前排序。 [...]

[...] In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. [...]

但是不管,即使它是定义明确的表达式,如下所示:

but regardless, even if it is well defined expression like this:

++a = getSomeInt();

难以阅读和维护,应避免使用更简单的代码。

are difficult to read and maintain and should be eschewed for simpler code.

更新2

不知道我是如何错过这个beofre的,但是您没有初始化 a 此处:

Not sure how I missed this beofre but you are not initializing a here:

 int a;

所以它将具有不确定值,我们不知道它的初始值是什么,并且在 a 上执行 pre-increment 也将是未定义的行为

and so it will have an indeterminate value, we don't know what it's initial value will be and performing a pre-increment on a would also be undefined behavior.

这篇关于前缀和后缀运算符的怪异行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆