加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 前缀和后缀运算符的奇怪行为

发布时间:2020-12-16 09:48:27 所属栏目:百科 来源:网络整理
导读:为什么第一个表达式允许,但第二个表达式不允许: void test(){ int a; ++a = getSomeInt(); a++ = getSomeInt();} 我的意思是,为什么禁止第二个成为左值?第二个是有道理的,第一个没有.在第一个我们增加变量,并在我们给这里一个新值后立即失去它.在第二个表
为什么第一个表达式允许,但第二个表达式不允许:

void test()
{
   int a;

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

我的意思是,为什么禁止第二个成为左值?第二个是有道理的,第一个没有.在第一个我们增加变量,并在我们给这里一个新值后立即失去它.在第二个表达式中并非如此.在此之后分配一些值并增加变量是有意义的.

解决方法

后缀增量的结果是prvalue,表示 pure rvalue,因此不可修改.这是根据 draft C++ standard下的后缀表达式部分5.2.6增量和减量表示(强调我的):

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. […]

如果你考虑它,这是有道理的,因为你需要返回它的前一个值必须是一个临时值.

为了完整起见,5.3.2增量和减量中的前缀增量语言(强调我的):

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中调用undefined behavior,我们可以看到,通过查看older draft standard中的相关部分,将是第5节表达式第4段,其中说:

[…]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.

因此,由于您不止一次修改它,因此未定义.据我所知,这在C11中有明确定义,在第1.9节中,程序执行第15段说:

Except where noted,evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. […] If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object,the behavior is undefined.

我们可以在5.17节中看到赋值和复合赋值运算符第1段说:

[…] 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. […]

但无论如何,即使它是如此明确定义的表达式:

++a = getSomeInt();

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

更新2

不确定我是如何错过这个但是你没有在这里初始化:

int a;

因此它将具有不确定的值,我们不知道它的初始值是什么,并且对a执行预增量也将是未定义的行为.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读