C语言 side effect 和 sequence point

news/2024/7/8 4:36:14

C语言 side effect 和 sequence point

  126人阅读  评论(0)  收藏  举报
语言 c object 编译器 function file
  C 语言中,术语副作用(side effect)是指对数据对象或者文件的修改。例如,以下语句        var = 99;
的副作用是把 var 的值修改成 99。对表达式求值也可能产生副作用,例如:
        se = 100
对这个表达式求值所产生的副作用就是 se 的值被修改成 100。
     序列点(sequence point)是指程序运行中的一个特殊的时间点,在该点之前的所有副作用已经结束,并且后续的副作用还没发生。
    C 语句结束标志——分号( ;)是序列点。也就是说, C 语句中由赋值、自增或者自减等引起的副作用在分号之前必须结束。我们以后会说到一些包含序列点的运算符。任何 完整表达式(full expression)运算结束的那个时间点也是序列点。所谓完整表达式,就是说这个表达式不是 子表达式。而所谓的子表达式,则是指表达式中的表达式。例如:
        f = ++e % 3
这整个表达式就是一个完整表达式。这个表达式中的 ++e、3 和 ++e % 3 都是它的子表达式。
    有了序列点的概念,我们下面来分析一下一个很常见的错误:
        int x = 1, y;
        y = x++ + x++;
这里 y = x++ + x++ 是完整表达式,而 x++ 是它的子表达式。这个完整表达式运算结束的那一点是一个序列点,int x = 1, y; 中的 ; 也是一个序列点。也就是说,x++ + x++ 位于两个序列点之间。标准规定, 在两个序列点之间,一个对象所保存的值最多只能被修改一次。但是我们清楚可以看到,上面这个例子中,x 的值在两个序列点之间被修改了两次。这显然是错误的!这段代码在不同的编译器上编译可能会导致 y 的值有所不同。比较常见的结果是 y 的值最后被修改为 2 或者 3。在此,我不打算就这个问题作更深入的分析,各位只要记住这是错误的,别这么用就可以了。有兴趣的话,可以看看以下列出的相关资料。
C 语言标准对副作用和序列点的定义如下:
    Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment. Evaluation of an expression may produce side effects. 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.
翻译如下:
    访问易变对象,修改对象或文件,或者调用包含这些操作的函数都是副作用,它们都会改变执行环境的状态。计算表达式也会引起副作用。执行序列中某些特定的点被称为序列点。在序列点上,该点之前所有运算的副作用都应该结束,并且后继运算的副作用还没发生。

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

相关文章

L3-005. 垃圾箱分布

L3-005. 垃圾箱分布 题目链接:https://www.patest.cn/contests/gplt/L3-005 Dijstra 与L2-001.紧急救援类似,是Dijstra最短路的拓展,要注意排序是按照: 1.到所有居民点的最小距离的最大; 2.平均距离最短; 3…

java-对象的理解-对象在内存的存储

String str; 这段代码表示创建一个名叫str的String类型的reference。 这个reference保存在栈stack中,速度很快,但它并没有保存词或者句子的数据,它仅仅是目标数据的一个指向。 如果此时向str发送一个消息,就会返回一个运行时错误&…

怎么设置自定义Tabbar的文字大小 -------ios

系统默认的tabbar感觉好小,很丑,于是得自己来设置它的大小 我们需要在 (void)load 或者在 (void)initialize 里设置 那这两个方法有什么区别呢 可以看这里 :(转载)http://www.jianshu.com/p/9368ce9bb8f9 我们在这里…

删除两个双向循环链表的相同节点

删除两个双向循环链表的相同节点 分类: Data Structure 面试题集2011-09-23 12:37 1242人阅读 评论(1) 收藏 举报nulldeletestructsystemc有两个双向循环链表A,B,知道其头指针为:pHeadA,pHeadB,请写一个函数…

Unity Shader - Simple Toon Shading - 简单卡通渲染

文章目录最终效果 - Final Effect无光照,只有纹理与主色调Shader加描边 - OutlineGIFShader添加光影 - RecieveShadow自身接收阴影Shader调整阴影 - Adjusting Shadow ParamsShader无透视法线挤出描边Shader整体运行效果高光 - SpecularShader边缘光 - RimShader控制…

javascript(十五) 错误处理技术

为什么80%的码农都做不了架构师?>>> 错误处理技术 常见的异常EvalError, RangeError ,ReferenceError ,SyntaxError ,TypeError ,URIError 其他就是语法规则try {}catch…

给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数

给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数 分类: c/c 数据结构算法2011-07-16 22:40 594人阅读 评论(0) 收藏 举报[cpp] view plaincopyprint? /* 给定一个存放整数的数组,重新排列数组使得数组左边为…

开源大数据周刊-第8期

阿里云E-Mapreduce动态 E-Mapreduce团队 1.3.2版本(已经发布): Master HA功能1.4版本(正在研发): 用户执行计划及集群运行状态自定义报警集群整体运行情况的仪表盘集群的一些专家建议,例如:扩容…