为什么“i = ++ i + 1”未指定行为? [英] Why is `i = ++i + 1` unspecified behavior?

查看:135
本文介绍了为什么“i = ++ i + 1”未指定行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下C ++标准ISO / IEC 14882:2003(E)引文(第5节,第4段):


注意到,对单个
运算符的操作数和单个
表达式的子表达式的
求值的顺序以及发生副作用的
中的顺序是未指定的
。 53)在前面的
和下一个序列点之间,标量
对象应该通过表达式的
求值使它的存储值
最多修改一次。
此外,先前的值应该是
,仅被访问以确定要存储的值
。这个
段的要求应满足每个
允许的完整表达式的
子表达式的顺序;
否则行为是未定义的。
[例如:

  i = v [i ++] //行为未指定
i = 7,i ++,i ++; //我变成9

i = ++ i + 1; //行为未指定
i = i + 1; // i的值增加

-end示例]


我很惊讶, i = ++ i + 1 给出了一个未定义的值 i
任何人都知道一个编译器实现,对于下面的情况不会给出 2

  int i = 0; 
i = ++ i + 1;
std :: cout<< i<< std :: endl;

事实是 operator = args。第一个总是 i 引用。
在这种情况下,评估的顺序无关紧要。
除了C ++标准禁忌,我没有看到任何问题。



,不要参数的顺序对评价很重要的情况。例如, ++ i + i 显然是未定义的。请考虑只有我的情况
i = ++ i + 1




解决方案 code>作为双参数函数,其中参数的副作用必须在函数开始之前完全求值。如果是这样,那么表达式 i = ++ i + 1 将有多个序列点,而 ++ i 将在赋值开始之前完全评估。不是这样的。在内部赋值运算符中评估的内容,而不是用户定义的运算符。



++ i 的结果在赋值之前(并且在加法运算符之前)被评估,但是 不一定立即应用。 ++ i + 1 的结果总是与 i + 2 相同,因此这是赋值的值到 i 作为赋值运算符的一部分。 ++ i 的结果总是 i + 1 ,所以这是分配给 i 作为增量运算符的一部分。没有序列点来控制应该首先分配哪个值。



由于代码违反了上一个和下一个序列点之间的标量对象其存储值最多通过表达式的求值修改一次,行为未定义。 实际上,可能 i + 1 i + 2 先分配,然后分配另一个值,最后程序将继续运行 - 没有鼻子恶魔或爆炸厕所,也没有 i + 3 。 / p>

Consider the following C++ Standard ISO/IEC 14882:2003(E) citation (section 5, paragraph 4):

Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified. 53) 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. [Example:

i = v[i++];  // the behavior is unspecified 
i = 7, i++, i++;  //  i becomes 9 

i = ++i + 1;  // the behavior is unspecified 
i = i + 1;  // the value of i is incremented

—end example]

I was surprised that i = ++i + 1 gives an undefined value of i. Does anybody know of a compiler implementation which does not give 2 for the following case?

int i = 0;
i = ++i + 1;
std::cout << i << std::endl;

The thing is that operator= has two args. First one is always i reference. The order of evaluation does not matter in this case. I do not see any problem except C++ Standard taboo.

Please, do not consider such cases where the order of arguments is important to evaluation. For example, ++i + i is obviously undefined. Please, consider only my case i = ++i + 1.

Why does the C++ Standard prohibit such expressions?

解决方案

You make the mistake of thinking of operator= as a two-argument function, where the side effects of the arguments must be completely evaluated before the function begins. If that were the case, then the expression i = ++i + 1 would have multiple sequence points, and ++i would be fully evaluated before the assignment began. That's not the case, though. What's being evaluated in the intrinsic assignment operator, not a user-defined operator. There's only one sequence point in that expression.

The result of ++i is evaluated before the assignment (and before the addition operator), but the side effect is not necessarily applied right away. The result of ++i + 1 is always the same as i + 2, so that's the value that gets assigned to i as part of the assignment operator. The result of ++i is always i + 1, so that's what gets assigned to i as part of the increment operator. There is no sequence point to control which value should get assigned first.

Since the code is violating the rule that "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," the behavior is undefined. Practically, though, it's likely that either i + 1 or i + 2 will be assigned first, then the other value will be assigned, and finally the program will continue running as usual — no nasal demons or exploding toilets, and no i + 3, either.

这篇关于为什么“i = ++ i + 1”未指定行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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