4

从过去几天开始,我试图了解未定义的行为。几天前,我找到了一个c-faq链接。这有助于消除许多困惑,但是当我阅读问题#3.8时又造成了另一个很大的困惑。经过我的大量努力来理解该陈述(特别是第二句);

该标准指出

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

我觉得在 SO 上问这个问题更好,但那里的答案都没有解释这个陈述的第二句话。最后,我在那里得到了关于这一点的解释。在多次阅读它和常见问题解答后,我得出结论

1.最后一句话

此外,只能访问先验值以确定要存储的值

会是这样的;

此外,仅应访问对象的先前值以确定要存储的(同一对象的)修改/新值 。

正如示例所清楚的那样

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

在表达式的情况下,访问(在 RHS 中)的i = i + 1先验值(在1此处)i以确定i要存储的值。而在 and 的情况下j = i + 1a[i] = ii 的访问值只是值 而不是 先前值,因为i 在这些语句中没有修改 where 。

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

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

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

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

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

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

4

1 回答 1

2

这样想:

a = i++;

相当于:

a = i;
i++;

访问i增量中的值与确定 a 将存储到 a 中的值无关。Soi = i++包含对 of 的两个修改i(第一句不允许这样做),而且对i =to 的修改i独立于对 in 的访问i之一i++

我想有人只是在那里特别聪明。无需计算未定义的行为有多少是未定义的。修改一个值两次就足够了。

于 2013-07-11T15:33:00.140 回答