未定义的行为和序列点 [英] Undefined behavior and sequence point

查看:183
本文介绍了未定义的行为和序列点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去几天,我试图了解未定义的行为。几天前,我发现了一个 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 is 1 here) of i (in R.H.S) is accessed to determine the value of i to be stored. While in case of j = i + 1 and a[i] = i, the accessed value of i is just value not prior value as no where i is modified in these statements.

2.In case of expression a[i] = i++ or a[i++] = i, first sentence of above statement

Between 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 of i accessed two times i.e, i++ itself access prior value of i in the expression to modify it and hence other access of prior value / value of i 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-faq

Actually, 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 of i.
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. So i = i++ contains two modifications of i (which is disallowed by the first sentence), but also, the i = modification to i is independent from one of the accesses to i in i++.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆