就序列点而言,预增量与后增量 [英] Preincrement vs postincrement in terms of sequence points

查看:80
本文介绍了就序列点而言,预增量与后增量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此答案中,有一些定义明确和不确定的表达式示例。我对其中的两个特别感兴趣:

 (6)i = i ++ +1; //未定义行为
(7)i = ++ i + 1; //行为明确的

这意味着递增前和递后序列点之间存在差异和定义明确的/未指定/未定义的行为,但我不明白这种差异的来源。


在标准草案( N4618 )中,有一个代码示例([介绍执行],第18页)


i = i ++ +1; // i的值递增


i = i ++ + i; //行为未定义


据我所知,这表示表达式 i = i ++ + 1 应该定义清楚,变量 i 的值应该增加 1 作为该表达式的结果。但是,此代码在MSVS 2015中运行会使 i 增加 2


那么,表达式 i = i ++ + 1 会发生什么?它是定义明确,未定义,实现定义还是未指定的行为?如原始答案中所述,就序列点和UB而言,此增量与相似表达式中的增量前和增量后有什么区别吗?以及为什么Visual Studio显示的行为不同于标准编写的行为?


请注意,我主要对现代c ++(14/17)感兴趣。

解决方案

表达式 i = i ++ + 1 会发生什么?



这个确切的例子在标准中给出了,我们有多幸运?


N4296 1.9.15 [intro.execution]



i = i ++ +1; //行为未定义


当然,我们想知道为什么。以下标准报价似乎与此处相关:


N4296 1.9.15 [intro.execution] p>

[...]在对运算符结果进行值计算之前,对运算符操作数的值计算按
进行排序。 [...]


这告诉我们,总和将发生在赋值之前(h,它又如何知道赋值什么!),但不能保证增量会在分配之前或之后发生,现在我们处在模糊的环境中……


N4296 1.9.15 [intro.execution]



[...]如果相对于标量对象的副作用未排序
对同一标量对象有另一个副作用,或者使用同一标量对象的值进行值计算
,并且它们不是
潜在并发(1.10),因此行为未定义。 [...]


赋值运算符对 i ,这意味着我们对同一个标量对象有两个副作用(另一个是 i ++ 执行的赋值),它们是无序列的,是不确定的。



为什么Visual Studio显示的行为不同于标准编写的行为?



没有。该标准说它是未定义的,这意味着它可以做任何事情,从您想要的到完全不同的事情,碰巧这就是编译器吐出来的行为!


In this answer there're some examples of well-defined and undefined expressions. I'm particularly interested in two of them:

(6) i = i++ + 1;    // Undefined Behaviour
(7) i = ++i + 1;    // Well-defined Behaviour

This means that there's a difference between pre-increment and post-increment in terms of sequence points and well defined /unspecified/undefined behavior, but I don't understand where this difference comes from.

In standard draft (N4618) there's an example of code ([intro.execution], pt 18)

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

i = i++ + i; // the behavior is undefined

Which, as far as I understand, means that expression i = i++ + 1 should be well-defined and the value of a variable i should increase by 1 as the result of this expression. However, this code run in MSVS 2015 increases i by 2.

So, what happens in the expression i = i++ + 1? Is it well-defined, undefined, implementation-defined or unspecified behavior? And is there any difference between pre-increment and post-increment in this and similar expressions in terms of sequence points and UB, as stated in the original answer? And why Visual Studio shows the behavior which is different from written in standard?

Please also note that I'm primarily interested in modern c++ (14/17).

解决方案

What happens in the expression i = i++ + 1? Is it well-defined, undefined, implementation defined or unspecified behaviour?

This exact example is given in the standard, how lucky are we?

N4296 1.9.15 [intro.execution]

i = i++ + 1; // the behavior is undefined

Of course, we'd like to know why too. The following standard quote appears to be relevant here:

N4296 1.9.15 [intro.execution]

[ ... ] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. [ ... ]

This tells us that the sum will occur before the assignment (duh, how else does it know what to assign!), but it doesn't guarantee that the increment will occur before or after the assignment, now we're in murky water...

N4296 1.9.15 [intro.execution]

[ ... ] 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, and they are not potentially concurrent (1.10), the behavior is undefined. [ ... ]

The assignment operator has a side effect on the value of i, which means we have two side effects (the other is the assignment performed by i++) on the same scalar object, which are unsequenced, which is undefined.

Why does Visual Studio show the behavior which is different from written in standard?

It doesn't. The standard says it's undefined, which means it can do anything from what you wanted to something completely different, it just so happens that this is the behaviour that got spat out by the compiler!

这篇关于就序列点而言,预增量与后增量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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