2013-07-10 32 views
4

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

标准指出

之前和下一sequence point之间的对象应具有其存储的值由表达式的评估修饰的至多一次。此外,只有在确定要存储的值时才能访问先前值。

我感觉好多问这个question对SO,但没有答案的解释出现这一声明的第二句。最后,我得到了关于这一点的explanation。看了它和FAQ后很多次我总结了那个;

1.最后一句

此外,前一个值是唯一的访问,以确定该值将被存储

会是这样;

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

由于它是由示例清楚

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

在表达的情况下i = i + 1先前值(这是1这里)的i(在RHS)被访问以确定的i值设定为存储。而在j = i + 1a[i] = i情况下,i的访问的值是只是重视现有值作为没有在那里i在这些语句修改。表达a[i] = i++a[i++] = i

2.In情况下,上面的语句

之前和下一序列点之间的第一句的对象应由的评价已修改至多一次其存储的值表达。

i连续两个序列点之间修改只有一次获得失败。这就是为什么我们需要第二句话。
这两个例子是使用C不允许的,因为的i先前值访问两次,即,i++本身存取i先前值在表达式对其进行修改和先前值/值的,因此其他访问的i是因为它不被访问来确定要被存储的修改值。

问题开始时我想到了关于它在C-FAQ

其实陈述表达i = i++,我们一直在讨论的其它表达式违反第二句,如好。

我想在这个表达式i(在R.H.S)被访问以确定的i修改后的值。
这个表达式如何违反第二条语句?

回答

3

想想这样说:

a = i++; 

等同于:

a = i; 
i++; 

的访问在增量i值无关与确定将被储存什么样的价值变成一个。因此,i = i++包含i(这是第一句不允许的)的两个修改,而且,对ii =修改与对i的访问之一是独立的。

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

+0

R.H.S中访问了多少次'i'? – haccks

+0

好吧,要迂腐,它没有定义它被访问多少次,因为整个表达式是不确定的。 – Art