• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 关于C/C++中的side effect(负效应)和sequence point(序列点)

关于C/C++中的side effect(负效应)和sequence point(序列点)

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了sequence effect,sequence,sequence什么意思,boot sequence,sequence of total等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

不知你在写code时是否遇到这样的问题?int i = 3; int x = (++i) + (++i) + (++i); 问x值为多少?进行各种理论分析,并在编译器上实践,然而可能发现最终的结果是不正确的,也是不稳定的,不同的编译器可能会产生不同的结果。这让人很头疼。结果到底是啥呢?对于此题的答案,一句话,Theresult 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种情况:

1、At the end of a full expression
在一个完整的表达式末尾是Sequence Point,所谓完整的表达式是指这个表达式不是另外一个表达式的一部分。所以如果有f(); g();这样两条语句,f()和g()是两个完整的表达式,f()的Side Effect必定在g()之前发生。

2、After the evaluation of all function arguments in a function call and before execution of any expressions in the function body
调用一个函数时,在所有准备工作做完之后、函数调用开始之前是Sequence Point。比如调用foo(f(), g())时,foo、f()、g()这三个表达式哪个先求值哪个后求值是Unspecified,但是必须都求值完了才能做最后的函数调用,所以f()和g()的Side Effect按什么顺序发生不一定,但必定在这些Side Effect全部作用完之后才开始调用foo函数。

3、After copying of a returned value and before execution of any expressions outside the function
函数即将返回时是Sequence Point,因为函数返回时必然会结束掉一个完整的表达式。

4、After evaluation of the first expression in a&&b,  a||b,  a?b:c,  or  a,b
条件运算符?:、逗号运算符、逻辑与&&、逻辑或||的第一个操作数求值之后是Sequence Point。如条件运算符和逗号运算符,条件运算符要根据表达式1的值是否为真决定下一步求表达式2还是表达式3的值,如果决定求表达式2的值,表达式3就不会被求值了,反之也一样,逗号运算符也是这样,表达式1求值结束才继续求表达式2的值。

5、After the initialization of each base and member in the constructor initialization list
在一个完整的声明末尾是Sequence Point,所谓完整的声明是指这个声明不是另外一个声明的一部分。比如声明int a[10], b[20];,在a[10]末尾是Sequence Point,在b[20]末尾也是。

经过以上说明,大家已有所了解,现在回到我们的题目:int x = (++i) + (++i) + (++i); 整个的语句里面,只有1个Sequence Point,也就是语句的结束点,对于右边表达式的计算顺序没有任何的规定,显然,各种编译器都可以按照他们觉得“舒服”的方式来进行计算,这样的代码,如果只要求在特定的平台或者编译器运行,那么带来的可能只是可读性差的问题,但如果考虑跨平台或者编译器的情况,那么就是完完全全的错误!

另外,需要特别注意的是,对于赋值号(assignment operator),C++也没有把它定义成Sequence Point,也就说这样的语句:buffer[i] = i++;同样是undefined的,因为,对于等号左右两边的表达式运算顺序,你并不能有任何的假定。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 关于C/C++中的side effect(负效应)和sequence point(序列点)

相关文章

  • 2017-05-28详解C语言的结构体中成员变量偏移问题
  • 2017-05-28C语言 全局变量和局部变量详解及实例
  • 2017-05-28c语言读取csv文件和c++读取csv文件示例分享
  • 2017-05-28在C语言中使用对数函数的方法
  • 2017-05-28C语言之字符串模糊查询方法的实现
  • 2017-05-28C/C++ 中sizeof('a')对比详细介绍
  • 2017-05-28常用C/C++预处理指令详解
  • 2017-05-28详解socket阻塞与非阻塞,同步与异步、I/O模型
  • 2017-05-28C++中的常量定义小结
  • 2017-05-28深入理解void以及void指针的含义

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • NSString与C字符串之间的相互转换
    • 详解C++中基类与派生类的转换以及虚基类
    • 使用C语言递归与非递归实现字符串反转函数char *reverse(char *str)的方法
    • C程序读取键盘码的方法
    • C#使用反射加载多个程序集的实现方法
    • 浅析结束程序函数exit, _exit,atexit的区别
    • C字符串与C++中string的区别详解
    • sdl显示一张bmp图片示例
    • C语言的数组学习入门之对数组初始化的操作
    • 浅谈C++中的mutable和volatile关键字

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有