免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 10719 | 回复: 21
打印 上一主题 下一主题

什么是sequence point? [复制链接]

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-04-22 17:44 |只看该作者 |倒序浏览
RT:
哪位能给我解释一下吗?

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
2 [报告]
发表于 2004-04-22 22:09 |只看该作者

什么是sequence point?

no one can help?

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
3 [报告]
发表于 2004-04-27 17:16 |只看该作者

什么是sequence point?

唉好失望啊.

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
4 [报告]
发表于 2004-04-27 20:11 |只看该作者

什么是sequence point?

你看哪里看来的?
把原文贴出来。让大家帮你看看。
就给一个概念,谁知道是怎么回事呀。

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
5 [报告]
发表于 2004-04-27 20:30 |只看该作者

什么是sequence point?

不知是:
"C++规定两个sequence point之间,一个值只能被写一次"正确还是:
"C++规定一个sequence point之间,一个值只能被写一次"正确.

论坛徽章:
0
6 [报告]
发表于 2004-04-27 21:44 |只看该作者

什么是sequence point?

表达式的计算分为两种,一种是有副作用的计算,如:
(++x)+y
一种是无副作用的计算,如:
x*y

有副作用的计算中,子表达式的计算顺序是重要的。例如
(++x)*(x+1)
当x=0时,如果先算++x,上式计算结果为2,如果先算x+1,上式计算结果为1。
再如,对函数g(int, int)的调用g(x, ++x), 当x=1,这个调用是g(1, 2)还是g(2, 2)?

所谓“顺序点”,和表达式的副作用紧密相关。再看这个例子:

(++i) + (++j)

这个表达式的计算,有两个副作用:
i自增1;
j自增1;
但是到底哪一个先发生?答案是:任何答案都不对。

为什么?因为标准并不定义副作用发生的顺序。标准只保证,一个表达式的全部副作用,不在达到该表达式紧邻的前一顺序点前发生,并且一定在达到该表达式紧邻的下一个顺序点之前发生完毕。

一个顺序点,被定义为程序执行过程中的这样一个点:该点前的表达式的所有副作用,在程序执行到达该点之前发生完毕;该点后的表达式的所有副作用,在程序执行到该点时尚未发生。

(++i) + (++j)这个表达式本身不包含顺序点,所以i++,j++这两个“副作用”到底谁先发生,根据标准,是未定义的。如果给这个表达式加上顺序点,如:
;(++i) + (++j);
标准只保证,这两个副作用在整个表达式求值完成前(即到达后面的顺序点";"前)都会发生,并且不会在上一个语句执行完毕之前发生。

标准还规定,两个相邻顺序点之间,对某一表达式求值,最多只能造成任一特定对象的值被更改一次。如果表达式求值过程会更改某对象的值,那么要求更改前的值被读取的唯一目的,只能是用来确定要存入的新值。
例如下面的表达式,按照标准规定,执行结果是未定义的:
(i++)+(i++)
这个表达式本身不包含任何顺序点,但是对这个表达式求值,按照运算符定义,将更改i两次,违反了“一次更改”的要求。
再看下面的表达式,按照标准规定,执行结果也是未定义的:
x=i++
这个表达式本身不包含任何顺序点,虽然i的值只更改了一次,但是x这个左值中,i被读取,用于确定数组中被修改的元素的下标。这次对i求值和i++肯定位于同一对顺序点之间,该表达式求值过程更改了i的值,x中读取i却不是为了确定i的新值,这违反了“读取只能用于确定新值”规定。

任何对相邻顺序点间表达式求值的多个副作用发生的顺序进行假设,或者违反上述“一次更改、读取仅用于确定新值”规定的代码,其执行结果都是未定义的。这里所说的“未定义”,通常比“不可移植”更严重,可以认为是“错误”的同意词。

通常我们认为,标准对“顺序点”及其语义的定义,是为了严谨地定义C/C++的表达式和求值过程,并不是为了让程序员通过对顺序点的掌握,(过分地)利用表达式求值的副作用。实际工作中,我们完全可以通过引入中间变量,避开“顺序点”这样容易出错,也极大地降低代码可读性的“边缘概念”。

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
7 [报告]
发表于 2004-04-28 22:55 |只看该作者

什么是sequence point?

为什么说:
(++x)+y 有副作用
(++i) + (++j) 有两个副作用呢?
我觉得这两个表达式不管如何计算也不会影响结果吧?
哪来副作用呢?

(++x)*(x+1)
这种表达式说有副作用还可以理解,毕竟两个子表达式的计算顺序会影响表达式的结果.

能解释一下这里的副作用吗?
我觉得副作用就是表达式的计算顺序会影响表达式的结果.对不对?

论坛徽章:
0
8 [报告]
发表于 2004-04-29 09:56 |只看该作者

什么是sequence point?

原帖由 "THEBEST"]我觉得副作用就是表达式的计算顺序会影响表达式的结果.对不对?[/quote 发表:

不对。当你写出违反顺序点定义的表达式的时候,子表达式求值的顺序会影响表达式的结果,这种情况正是标准希望通过“顺序点”的定义来避免的情况。
如果你不违反顺序点的定义,子表达式求值的顺序则不会影响整个表达式的结果,但是一个符合顺序点定义,计算顺序不影响其结果的表达式,仍然可以有副作用。所谓副作用,是相对传统意义上的“表达式”来说的。
例如,传统表达式的计算过程,运算符不会令参与计算的变量本身的值发生改变;而C/C++语言的表达式中由于++, --等运算符的介入,表达式求值可能导致参与计算的变量本身的值发生改变。这就是一种可能的副作用。

[quote]原帖由 "THEBEST" 发表:
为什么说:
(++x)+y 有副作用
(++i) + (++j) 有两个副作用呢?
我觉得这两个表达式不管如何计算也不会影响结果吧?
哪来副作用呢?

如果单从表达式本身的计算结果看,这两个表达式的副作用当然不会影响整个表达式的值;在C语言中对表达式 (++i) + (++j) 求值,会使i的值加一,j的值加一。你不对这两件事发生的顺序作假设,而只关心整个表达式的最终结果。从这个意义上说,你写的这个表达式符合顺序点的定义,因而它的计算结果,按照标准定义,是没有歧义的。整个表达式的“计算结果没有歧义”不等于说它“没有副作用”,i和j的值发生改变正是这个表达式求值的副作用。

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
9 [报告]
发表于 2004-04-29 12:22 |只看该作者

什么是sequence point?

你说的"顺序点"的概念怎么我理解起来就像是;一样呢?
比如一个语句的结束就是一个顺序点产生,而这个语句前面的;(顺序点)就表示下一个语句产生.....是不是这样呢?
如果表达式求值过程会更改某对象的值,那么要求更改前的值被读取的唯一目的,只能是用来确定要存入的新值。

更改前的值被读取的唯一目的吗?
x=i++ 这个表达式中x 中读取i是更改后啊.
如何理解"更改前的值被读取只能是为了确定要存入的新值"呢?

论坛徽章:
0
10 [报告]
发表于 2004-04-29 12:53 |只看该作者

什么是sequence point?

唉……看来还是我表达能力不行啊。算了我们私下说吧,再这么讨论下去非得让斑竹当成版聊帖子删除了不可。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP