- 论坛徽章:
- 0
|
什么是sequence point?
算了,既然斑竹发话说没有关系,那我就再发最后一篇来解释这个问题。本来是希望用最简短的文字解释清楚,没想到越是想简洁越是没说清。
C语言中,只包含一个表达式的语句,如
x = (i++) * 2;
称为“表达式语句”。表达式语句结尾的";"是C标准定义的顺序点之一,但这不等同于说所有的";"都是顺序点,也不是说顺序点只有这一种。下面就是标准中定义的顺序点:
函数调用时,实参表内全部参数求值结束,函数的第一条指令执行之前(注意参数分隔符“,”不是顺序点);
&&操作符的左操作数结尾处;
||操作符的左操作数结尾处;
?:操作符的第一个操作数的结尾处;
逗号运算符;
表达式求值的结束点,具体包括下列几类:自动对象的初值计算结束处;表达式语句末尾的分号处;do/while/if/switch/for语句的控制条件的右括号处;for语句控制条件中的两个分号处;return语句返回值计算结束(末尾的分号)处。
定义顺序点是为了尽量消除编译器解释表达式时的歧义,如果顺序点还是不能解决某些歧义,那么标准允许编译器的实现自由选择解释方式。理解顺序点还是要从定义它的目的来下手。
再举一个例子:
y = x++, x+1;
已知这个语句执行前x=2,问y的值是多少?
逗号运算符是顺序点。那么该表达式的值就是确定的,是4,因为按照顺序点的定义,在对x+1求值前,顺序点","前的表达式——x++求值的全部副作用都已发生完毕,计算x+1时x=3。这个例子中顺序点成功地消除了歧义。
注意这个歧义是怎样消除的。因为中间的顺序点使“相邻顺序点间对象的值只更改一次”的条件得到满足。
y = (x++) * (x++), 执行前x=2, y=?
答案是,因为这个表达式本身不包含顺序点,顺序点未能消除歧义,编译器生成的代码使y取4, 6(以及更多的一些可能值)都是符合标准定义的,程序员自己应为这个不符合顺序点定义的表达式造成的后果负责。
我对我自己的表达能力欠佳表示抱歉,但我的确不准备对这个问题再做更多的解释。我愿意引用《Expert C Programming》中的一段话,来给自己找一个下台阶:
However, the problem with standards manuals is that they only make sense if you already know what they mean. If people write them in English, the more precise they try to be, the longer, duller and more obscure they become. If they write them using mathematical notation to define the language, the manuals become inaccessible to too many people.
自然语言本身的不精确,往往容易造成越解释越不清楚的现象,而精确的数学语言,又已经超过包括我在内的大多数人的理解和应用能力。
谢谢the best提供的这个机会来检验对知识点的理解程度;也谢谢斑竹对这个讨论的支持。 |
|