未定义的行为和顺序点
从过去的几天,我试图了解未定义的行为。 几天前我发现了一个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 + 1
和a[i] = i
, a[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
是独立于访问的一个到i
在i++
。
我认为有人在那里更加聪明。 没有必要确定未定义的行为未定义多少。 修改一个值两次是不够的。
链接地址: http://www.djcxy.com/p/73193.html