未定义的行为和序列点 [英] Undefined behavior and sequence point
问题描述
过去几天,我试图了解未定义的行为。几天前,我发现了一个 c-faq 链接。这有助于清除许多混淆,但是当我阅读时,会产生另一个大的混乱#3.8 。经过我很多的努力才明白了(特别是第二句话);
标准规定:
一个href =http://en.wikipedia.org/wiki/Sequence_point =nofollow noreferrer>序列点一个对象应该通过一个表达式的评估来最多修改一个对象。此外,先前的值只能被访问以确定要存储的值。
我觉得最好问这个关于SO的问题,但没有答案解释了本声明的第二句话。最后,我有一个关于这一点的说明。经过阅读和常见问题多次我结束那个;
1.最后一句
此外,只能访问先前的值以确定要存储的值
< blockquote>
将是这样的;
此外,只能访问一个对象,以确定要存储的修改/新值(相同对象)。
由示例清楚
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
的情况下,i的访问值为 just 不 之前的值没有在这些语句中修改i
如果表达式a [i] = i ++
或a [i ++] =我
,上述语句的第一句
在上一个和下一个序列点之间对象应通过表达式的评估最多修改其存储值。
i
在两个连续的序列点之间修改一次 。这就是为什么我们需要第二句话。
这两个例子都不允许在C中,因为i
的先前值被访问了两次,即i ++
本身访问i
中的先前值,以修改它,因此其他访问i
的先前值/值是不必要的,因为它不被访问以确定要存储的修改值。
当我想出了在c-faq中陈述的表达式
i = i ++
时,问题开始了
实际上,我们一直在讨论的其他表达方式也违反了第二句话。
我认为在这个表达式中
我
(在RHS中)被访问以确定修改后的值i
。
此表达式是否违反了第二条语句?解决方案以这种方式想想:
a = i ++ ;
相当于:
a = i;
i ++;
访问
i
的值增加与确定将存储到一个中的值是无关的。所以i = i ++
包含两个修改i
(第一个句子不允许),而且i =
修改为i
独立于对i的访问之一
在i ++
。
我认为有人只是在那里更加聪明。没有必要确定未定义的行为是多少。修改值两次就足够了。
From past few days I was trying to learn about undefined behavior. Few days ago I found a c-faq link. This helps a lot to clear many confusions, but creates an another big confusion when I read the question #3.8. After my lots of efforts to understand the statement (specially second sentence);
The Standard states that
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.
I felt better to ask this question on SO but none of the answer there explained the second sentence of this statement. Finally, I got an explanation there about this point . After reading it and FAQ many times I concluded that;
1.The last sentence
Furthermore, the prior value shall be accessed only to determine the value to be stored
would be like this;
Furthermore, the prior value of an object shall be accessed only to determine the modified/new value( of same object ) to be stored.
As it is clear by the example
int i = 1, j, a[5]; i = i + 1; j = i + 1; a[i] = i;
in case of expression
i = i + 1
prior value (which is1
here) ofi
(in R.H.S) is accessed to determine the value ofi
to be stored. While in case ofj = i + 1
anda[i] = i
, the accessed value of i is just value not prior value as no wherei
is modified in these statements.2.In case of expression
a[i] = i++
ora[i++] = i
, first sentence of above statementBetween the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression.
get failed as
i
is modified only once between two consecutive sequence point. And that's why we need second sentence.
Both of these examples are disallowed in C because the prior value ofi
accessed two times i.e,i++
itself access prior value ofi
in the expression to modify it and hence other access of prior value / value ofi
is needless as it is not accessed to determine the modified value to be stored.The problem starts when I came up with the expression
i = i++
about which it is stated in c-faqActually, the other expressions we've been discussing are in violation of the second sentence, as well.
I think in this expression
i
(in R.H.S) is accessed to determine the modified value ofi
.
How this expression is violating the second statement?解决方案Think about it this way:
a = i++;
is equivalent to:
a = i; i++;
The accesses the value of
i
in the increment has nothing to do with determining what value a will be stored into a. Soi = i++
contains two modifications ofi
(which is disallowed by the first sentence), but also, thei =
modification toi
is independent from one of the accesses toi
ini++
.I think someone was just being extra clever there. There's no need to figure how much an undefined behavior is undefined. Modifying a value twice is enough undefined.
这篇关于未定义的行为和序列点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!