未定义的行为和序列点

时间:2013-07-10 14:57:41

标签: c undefined-behavior expression sequence-points

过去几天我试图了解undefined behavior。几天前我发现了一个c-faq链接。这有助于清除许多混淆,但在我阅读问题#3.8时又造成了另一个大混乱。经过我很多努力来理解陈述(特别是第二句);

标准规定

  

在上一个和下一个sequence point之间,一个对象的存储值最多只能通过表达式的计算修改一次。此外,只能访问先前值以确定要存储的值。

我觉得最好在question问这个问题,但没有一个答案解释了这个陈述的第二句话。最后,关于这一点,我得到了explanation。经过多次阅读和常见问题解答我总结了那个;

1.最后一句

  

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

会是这样的;

  

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

通过示例清楚

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

如果表达式i = i + 1,则1(在R.H.S中)的先前值(此处为i)被访问以确定要存储的i的值。在j = i + 1a[i] = i的情况下,i的访问值是只是值 而不是 之前的值为no其中i在这些陈述中被修改。

2.如果表达a[i] = i++a[i++] = i,则为上述陈述的第一句

  

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

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

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

  

实际上,我们讨论过的其他表达也违反了第二句话。

我认为在此表达式i(在R.H.S中)被访问以确定i的修改值。
此表达式如何违反第二个声明?

1 个答案:

答案 0 :(得分:3)

以这种方式思考:

a = i++;

相当于:

a = i;
i++;

在增量中访问i的值与确定将存储到a中的值无关。因此,i = i++包含i的两个修改(第一句话不允许),但i =i的修改独立于i的一个访问{1}}中的{1}}。

我认为有人在那里更加聪明。没有必要计算未定义的未定义行为的程度。修改两次值是不确定的。