关于C语言中"side effect(副作用)"定义的澄清问询
C语言中"副作用"的标准定义 vs 民间误解
直接给出结论:按照C17标准的定义,无论变量的作用域或存储类别如何,修改任何变量都属于副作用。
民间的狭义理解
很多开发者讨论中提到的“副作用”是狭义的——他们只把修改函数非局部内容的操作算作副作用,比如修改全局变量、静态变量,或者写入文件这类会影响函数外部环境的操作。至于修改当前代码块里的局部自动变量,因为它的影响范围仅限于当前函数栈帧,不会对外界产生可见影响,所以通常不被当成需要特别关注的“副作用”。这种理解是从实践中“影响范围”的角度出发,是开发者们约定俗成的关注点。
C17标准的广义定义
C17标准对副作用的定义要宽泛得多:
访问volatile对象、修改对象、修改文件,或调用执行上述任一操作的函数均为副作用,即执行环境状态的变化。
同时,标准6.2.4.1条款明确所有变量都属于“对象”的范畴——不管这个变量是局部的还是全局的,是自动存储还是静态存储。
从标准的字面意思来看,只要是修改了对象(包括局部自动变量),就属于执行环境状态的变化,自然符合副作用的定义。
两者的核心差异
民间的狭义理解关注的是“副作用是否对外界产生可见影响”,而标准的定义关注的是“是否改变了执行环境的状态”。标准的定义本质是为了约束编译器优化:任何带有副作用的操作,编译器都不能随意优化掉,哪怕这个副作用只存在于局部变量中——比如如果一个局部变量被修改后后续还会被使用,编译器就不能省略这个修改步骤,否则会破坏程序的执行逻辑。
内容的提问来源于stack exchange,提问作者BenevolentDeity
相关产品推荐
相关产品推荐

