过去几天我试图了解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 + 1
和a[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
的修改值。
此表达式如何违反第二个声明?
答案 0 :(得分:3)
以这种方式思考:
a = i++;
相当于:
a = i;
i++;
在增量中访问i
的值与确定将存储到a中的值无关。因此,i = i++
包含i
的两个修改(第一句话不允许),但i =
对i
的修改独立于i
的一个访问{1}}中的{1}}。
我认为有人在那里更加聪明。没有必要计算未定义的未定义行为的程度。修改两次值是不确定的。