【发布时间】:2019-08-26 04:40:37
【问题描述】:
来自ISO/IEC 9899:201x 部分5.1.2.3 程序执行 段落2:
访问易失性对象,修改对象,修改文件, 或调用执行任何这些操作的函数都是侧面 效果,即执行状态的变化 环境。表达式的评估通常包括 价值计算和副作用的开始。价值计算 对于左值表达式,包括确定 指定对象。
段落说“修改对象”是一个副作用。表示如下代码:
int x;
x = 1;
有一个副作用是x = 1,因为它修改了对象x。
然而,根据wikibooks 关于C 编程:
在 C 和更普遍的计算机科学中,函数或表达式 如果它在其范围之外修改状态,则据说有副作用 或与其调用函数或 外面的世界。按照惯例,返回值会影响 调用函数,但这通常不被视为副作用。
一些副作用是:
- 修改全局变量或静态变量
- 函数参数的修改
- 将数据写入显示器或文件
- 读取数据
- 调用其他副作用函数
那么,谁是对的? x = 1 真的是副作用吗?即使它没有改变其范围之外的任何东西?还是我错误地解释了标准?
【问题讨论】:
-
我认为 wiki 很困惑,并且使用术语“副作用”来表示不可优化/外部可见的副作用。正如 Erik Postpischil 在您提供的链接中所说,表达式评估的结果是主要效果。在评估期间发生的所有写入、易失性读取和系统调用都是其副作用,一些写入(或产生它们的函数调用)理论上可以在 as-if 规则下优化。
-
每个表达式都有一个值(除了 void 表达式)和 0 个或多个副作用。表达式
x = 1的值为1;它的副作用是将 1 分配给 x。您可以在更大的表达式中使用该值 (y = 4 - (x = 1)),但不能依赖副作用的执行顺序 (y = (x = 4) + (x = 2); /* y == 6; x == ?? */) -
@mpg 很好的解释,现在很有意义。
-
StoryTeller’s answer 是正确的,但我要补充一点,Wikibooks 文章对 副作用 给出了不同的定义,它对这些副作用的描述可能是正确的——但是这是该术语的不同用法。也就是说,这并没有错(因为人们可以使用他们自己的定义来定义术语;C 标准无权强制其他),但它应该明确表示它使用了一些非 C 定义。值得注意的是,这篇文章说“In C”是错误的。
标签: c language-lawyer side-effects