C/C++中的side effect

3 篇文章 0 订阅

Side effect直接翻译可以翻作“副作用”。通常情况下,程序员会认为在C函数中改变了全局变量这样的“不局限于函数局部状态”的动作就是有side effect。或者按照“虎书”(Morden Compiler implementation in C)中的说法,如果函数调用f(x)在一次计算的结果为a,那么下次计算f(x)的结果也必须为a。能够保证这样结果的函数,就是没有side effect的函数。

不过事实上,side effect在C/C++标准中的定义略有区别。在C++标准中,side effect其定义如下:

Accessing an object designated by a volatile glvalue (3.10), modifying an object, calling a library I/O function, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment.

简单地翻译下,就是访问volatile的变量,修改一个对象,或者作了I/O访问,以及调用了一个含有side effect的函数都被视为side effect。原因是:执行状态(这里指的是状态机)被改变了。volatile的访问和I/O访问可能比较容易理解,因为其可能影响其它线程甚至外设/文件系统的状态,不过这里面”修改一个对象“的条件常常让程序员迷惑。是否简单的赋值语句:

i = 1;

按照C/C++标准定义都会有side effect了呢?

首先需要搞清楚C/C++标准定义side effect的范围。通常side effect是用于描述一个表达式在evaluate(可以翻译为“计算”,不过不译为佳)时对状态机产生的副作用的(状态是否变迁)。因此这里的side effect针对的是表达式evaluation而非函数。

在C/C++语句中,每个表达式都会被evaluate(这在很多语言的解释器中都可以看到,每书写完一个语句总是会返回一个值)。而通常要evaluate一个表达式,可能获得两样东西,一个是表达式的值,另一个则是side effect。比如下面这个表达式:

i += 1;

按照C++标准定义,该表达式要evaluate的表达式等价于

i + 1

而该表达式的side effect则是将i + 1的值赋值给了变量i。这与普通命令式编程的概念是略有冲突的,因为通常程序员会认为赋值是“目的”,而并非“副作用”。不过按照C/C++标准的定义,赋值的的确确就是一种side effect。因此,在C/C++程序中,side effect是广泛存在的。实际上,在新的C++11/14标准中,尤其在描述多线程的部分,我们也大量地看到side effect的提法,而不是简单的assignment。

不过值得注意的是,一些初始化表达式,比如:

int i = 1;

则不存在side effect。(参见http://stackoverflow.com/questions/16221359/side-effects-in-c)。因为这里只是声明了一个初值为1的变量i,而不是改变变量i的值。

当然,虽然这里说的是C/C++,side effect也是编程语言中的一个通用的概念。当提及没有side effect的纯粹的函数式编程语言的时候,比如Haskell,side effect也是同样的概念。在这种定义下,C/C++程序员简单地认为所有变量都是const修饰的,或者说只能初始化,不能改变其值即可。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值