(++i)+(++i) 与 Sequence Point

news/2025/2/23 10:16:58
 看见有个面试题目,求x, y的值:

int i = 3, j = 3;
int x = (++i) + (++i) + (++i);
int y = (j++) + (j++) + (j++);

看到挺多人在争论,这样的表达式值应该是多少?甚至拿出几个不同的编译器来编译运行得到几个不同的结果。对于此题的答案,一句话,The behavior is undefined! 详细解释待我慢慢说来。

大家知道,通常而言,我们写的计算机程序都是从上到下,从左到右依次执行。然而,我只是说通常,因为在编译的过程中,compiler并不仅仅是把source code翻译成binary code就算了,这个过程里面可能还会对代码进行优化,这种优化可能带来的结果是:代码或者表达式evaluation的顺序可能发生变化。这可是一个非常严重的问题,当某个表达式带有side-effect(比如改变了一个变量的值),那么它的执行顺序直接影响到了程序执行的结果。

为了保证程序执行具有确定性的结果,C++标准引入Sequence Point这个概念,按照ISO/IEC的定义:

At certain specified points in the execution sequence called sequence points. All side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place.

简而言之,Sequence Point就是这么一个位置,在它之前所有的side effect已经发生,在它之后的所有side effect仍未开始,而两个Sequence Point之间所有的表达式或者代码执行的顺序是未定义的!

而C++标准又进一步规定了Sequence Point出现的5种情况:

  • At the end of a full expression
  • After the evaluation of all function arguments in a function call and before execution of any expressions in the function body
  • After copying of a returned value and before execution of any expressions outside the function
  • After evaluation of the first expression in a&&b,  a||b,  a?b:c,  or  a,b
  • After the initialization of each base and member in the constructor initialization list

具体我不详细讨论,只看第一个情况:At the end of a full expression,这里简化问题,full expression简单认为是一个带有;的语句(具体可以再去查标准)。也就是说,任何一个独立的表达式语句的结束都是一个Sequence Point,回到我们的题目:

int y = (++i) + (++i) + (++i);

整个的语句里面,只有1个Sequence Point,也就是语句的结束点,对于右边表达式的计算顺序没有任何的规定,显然,各种编译器都可以按照他们觉得“舒服”的方式来进行计算,这样的代码,如果只要求在特定的平台或者编译器运行,那么带来的可能只是可读性差的问题,但如果考虑跨平台或者编译器的情况,那么就是完完全全的错误!

另外,需要特别注意的是,对于赋值号(assignment operator),C++也没有把它定义成Sequence Point,也就说这样的语句:

buffer[i] = i++;

同样是undefined的,因为,对于等号左右两边的表达式运算顺序,你并不能有任何的假定。

http://www.cnblogs.com/levins/archive/2004/11/25/68572.html


http://www.niftyadmin.cn/n/1734647.html

相关文章

checkbox数组特性

<form name"searchList"><table><tr><td><input type"checkbox" name"key"></td></tr> </table>当checkbox有2个以上时,即表格有2行1. javascript中document.searchList.length2document.searc…

XMLDOM 参考

XMLDOM 参考 Back to Documentation Index XMLDOM 是用来访问和操作XML文档的编程接口规范。 简介 XMLDOM 被设计为可用于任何语言和任何操作系统。借助 DOM&#xff0c;程序员可以创建 XML 文档、遍历其结构&#xff0c;增、改、删其元素。DOM 将整个 XML 文档视作一棵树&…

Ajax 交流文档

Ajax 交流文档 Back to Documentation Index 使用 Ajax 的主要原因 通过适当的 Ajax 应用达到更好的用户体验。把以前的一些服务器负担的工作转嫁到客户端&#xff0c;利于客户端闲置的处理能力来处理&#xff0c;减轻服务器和带宽的负担&#xff0c;从而达到节约 ISP 的空间及…

Escape Sequences

http://msdn.microsoft.com/en-us/library/ms860944.aspx Escape Sequences Character combinations consisting of a backslash (\) followed by a letter or by a combination of digits are called “escape sequences.” To represent a newline character, single quotati…

define 的用法

http://baike.baidu.com/view/1441209.htm #define中的#与##   在#define中&#xff0c;标准只定义了#和##两种操作。#用来把参数转换成字符串&#xff0c;##则用来连接两个前后两个参数&#xff0c;把它们变成一个字符串。 #include <stdio.h> #define paster(n) p…

python函数的位置参数(Positional)和关键字参数(keyword)

python函数具有各种灵活的参数, 功能着实强大. 不过因为过于灵活, 故比较难于理清, 所以给初学者带来了不小的困扰. 以下是我搜集的资料, 力图将这个问题明朗化. 1. parameter 和 argument 以前一直认为这两个单词的含义是相同的, 今天才发现其实不然. parameter 为函…

python 条件判别中出现 “invalid syntax“ 错误的解释

今天用python写一个简单的脚本, 运行时却总是报错, 当时简直要手足无措了, 好在解决了. 现在把它记下来, 希望能够对其他人有所帮助. 问题代码如下: fIn open("d:/DeskTop/4通道数据.txt", "r", encoding"utf8") while s fIn.readline():pa…

由 WGestures 导致的 Win10系统莫名关机问题

之前有一段时间, 自己所用的win10系统运行一段时间后, 总是莫名奇妙的突然关机. 时间不固定, 有时次数也很频繁. 当时上网找了很多的解决办法, 但总也不奏效. 最后通过把shutdown.exe替换掉, 才勉强能用, 但仍然过一段时间就发现shutdown.exe被调用了.   本想追踪一下是什么程…