在this answer中,有一些定义良好和未定义表达式的示例。我对其中两个特别感兴趣:
(6) i = i++ + 1; // Undefined Behaviour
(7) i = ++i + 1; // Well-defined Behaviour这意味着,在序列点和定义良好的/未指定/未定义的行为方面,预置增量和后增量之间存在差异,但我不知道这种差异来自何处。
在标准草案(N4618)中,有一个代码示例(intro.execution,pt 18)。
i = i++ + 1; // the value of i is incrementedi = i++ + i; // the behavior is undefined
据我所知,这意味着表达式i = i++ + 1应该被很好地定义,并且作为这个表达式的结果,变量i的值应该由1增加。然而,在MSVS 2015中运行的这段代码增加了i的2。
那么,表达式i = i++ + 1会发生什么呢?它是定义明确的、未定义的、实现定义的还是未指定的行为?在这个和类似的表达式中,如原答案所述,在序列点和UB方面,前增量和后增量有什么区别吗?以及为什么Visual显示的行为不同于用标准编写的行为?
还请注意,我主要感兴趣的是现代c++ (14/17)。
发布于 2017-03-24 11:33:16
在表达式i = i++ + 1**?中发生了什么?它是定义明确的、未定义的、实现定义的还是未指定的行为?**
这个例子是在标准中给出的,我们有多幸运?
N4296 1.9.15 intro.execution
i = i++ + 1; // the behavior is undefined
当然,我们也想知道原因。以下标准报价似乎与此相关:
N4296 1.9.15 intro.execution ..。在运算符的结果计算值之前,对操作符的操作数的值计算进行排序。..。
这告诉我们,和将发生在赋值之前(嗯,它怎么知道分配什么!),但它不能保证增量会发生在分配之前或之后,现在我们陷入了泥潭.
N4296 1.9.15 intro.execution ..。如果对标量对象的副作用相对于对同一个标量对象的另一个副作用或使用同一个标量对象的值计算的另一个副作用没有排序,并且它们不具有潜在的并发性(1.10),则行为是未定义的。..。
赋值操作符对i的值有一个副作用,这意味着我们对同一个标量对象有两个副作用(另一个是i++执行的赋值),这些标量对象没有排序,也没有定义。
为什么Visual显示不同于用标准编写的行为?
它没有。标准说它是没有定义的,这意味着它可以做任何事情,从你想做的事情到完全不同的事情,只是碰巧的是,这是编译器抛出的行为!
https://stackoverflow.com/questions/42997644
复制相似问题