当前位置:嗨网首页>书籍在线阅读

08-副作用和顺序点

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

5.1.6 副作用和顺序点

下面更详细地介绍C++就递增运算符何时生效的哪些方面做了规定,哪些方面没有规定。首先,副作用(side effect)指的是在计算表达式时对某些东西(如存储在变量中的值)进行了修改;顺序点(sequence point)是程序执行过程中的一个点,在这里,进入下一步之前将确保对所有的副作用都进行了评估。在C++中,语句中的分号就是一个顺序点,这意味着程序处理下一条语句之前,赋值运算符、递增运算符和递减运算符执行的所有修改都必须完成。本章后面将讨论的有些操作也有顺序点。另外,任何完整的表达式末尾都是一个顺序点。

何为完整表达式呢?它是这样一个表达式:不是另一个更大表达式的子表达式。完整表达式的例子有:表达式语句中的表达式部分以及用作while循环中检测条件的表达式。

顺序点有助于阐明后缀递增何时进行。例如,请看下面的代码:

while (guests++ < 10)
     cout << guests << endl;

while循环将在本章后面讨论,它类似于只有测试表达式的for循环。在这里,C++新手可能认为“使用值,然后递增”意味着先在cout语句中使用guests的值,再将其值加1。然而,表达式guests++ < 10是一个完整表达式,因为它是一个while循环的测试条件,因此该表达式的末尾是一个顺序点。所以,C++确保副作用(将guests加1)在程序进入cout之前完成。然而,通过使用后缀格式,可确保将guests同10进行比较后再将其值加1。

现在来看下面的语句:

y = (4 + x++) + (6 + x++);

表达式4 + x++不是一个完整表达式,因此,C++不保证x的值在计算子表达式4 + x++后立刻增加1。在这个例子中,整条赋值语句是一个完整表达式,而分号标示了顺序点,因此C++只保证程序执行到下一条语句之前,x的值将被递增两次。C++没有规定是在计算每个子表达式之后将x的值递增,还是在整个表达式计算完毕后才将x的值递增,有鉴于此,您应避免使用这样的表达式。

在C++11文档中,不再使用术语“顺序点”了,因为这个概念难以用于讨论多线程执行。相反,使用了术语“顺序”,它表示有些事件在其他事件前发生。这种描述方法并非要改变规则,而旨在更清晰地描述多线程编程。