未定义的行为和顺序点

从过去的几天,我试图了解未定义的行为。 几天前我发现了一个c-faq链接。 这有助于清除许多混乱,但当我读到#3.8的问题时,又造成了另一个大混乱。 经过我多次努力了解陈述(特别是第二句);

该标准指出

在前一个和下一个序列点之间,一个对象应该通过评估一个表达式最多修改其存储值一次。 此外,只有在确定要存储的值时才能访问先前值。

我最好在SO上提出这个问题,但没有一个答案解释了这个陈述的第二句话。 最后,我在那里解释了这一点。 经过阅读和常见问题许多次, 我总结说:

最后一句

此外,只有在确定要存储的值时才能访问先前值

会是这样的;

此外, 对象的先前值只能用于确定要存储的修改/新值( 同一对象 )。

这个例子很明显

 int i = 1, j, a[5];    
 i = i + 1;
 j = i + 1;
 a[i] = i; 

在表达式i = i + 1情况下, i (在RHS中)的先前值(这里是1 )被访问以确定要存储的i的值。 而在j = i + 1a[i] = ia[i] = i的访问值只是值而不是先前值,因为在这些语句中i修改了i

2.在表达式a[i] = i++a[i++] = i ,上述语句的第一句话

在前一个和下一个序列点之间,一个对象应该通过评估一个表达式最多修改其存储值一次。

因为i在两个连续序列点之间只修改了一次,所以失败了 。 这就是为什么我们需要第二句话。
这两个例子在C中都是不允许的,因为i的前一个值访问了两次,即i++本身访问表达式中的i前一个值以修改它,因此其他访问i的先前值/值是不必要的,因为它没有被访问确定要存储的修改值。

当我想出关于它在c-faq中表达的表达式i = i++时,问题就开始了

实际上,我们一直在讨论的其他表达方式也违反了第二句话。

我认为在这个表达式中i (在RHS中)被访问以确定i的修改值。
这个表达如何违反第二条陈述?


这样想一想:

a = i++;

相当于:

a = i;
i++;

访问增量中的i的值与确定a将被存储到a中的值无关。 所以i = i++含有两个修饰i (其由第一句中不允许),而且,在i =修改i是独立于访问的一个到ii++

我认为有人在那里更加聪明。 没有必要确定未定义的行为未定义多少。 修改一个值两次是不够的。

链接地址: http://www.djcxy.com/p/73193.html

上一篇: Undefined behavior and sequence point

下一篇: Is the behavior of i = post