来自ISO / IEC 9899:201x第5.1.2.3节程序执行第2段:
访问易失性对象,修改对象,修改文件或调用执行任何这些操作的函数都是副作用,这些都是执行环境状态的变化。表达式的评估通常包括值计算和副作用的开始。左值表达式的值计算包括确定指定对象的身份。
该段说“修改对象”是一种副作用。这意味着以下代码:
int x;
x = 1;
有一个副作用,这是x = 1
,因为它修改对象x
。
但是,根据C编程的wikibooks:
在C中以及更一般地在计算机科学中,如果函数或表达式修改其范围之外的状态或者具有与其调用函数或外部世界的可观察的交互,则称该函数或表达具有副作用。按照惯例,返回值会对调用函数产生影响,但这通常不被视为副作用。
一些副作用是:
- 修改全局变量或静态变量
- 修改函数参数
- 将数据写入显示或文件
- 读数据
- 调用其他副作用函数
那么,谁是对的? x = 1
真的有副作用吗?即使它没有改变它的范围之外的任何东西?或者我错误地解释了标准?
那么,谁是对的?
当谈到标准中的定义时,它就是标准。
x = 1
真的有副作用吗?即使它没有改变它的范围之外的任何东西?
是的,你引用的标准段落说得那么多。
或者我错误地解释了标准?
您理解并正确地将标准段落应用于x = 1
。但是你试图在标准文本上应用外部口语定义是错误的。 C标准并不是要向任何人讲授C语言。它是一个正式文档,其唯一目的是定义C抽象机器如何执行翻译程序。为此,它定义了一堆概念和术语。而已。在引用这些术语以便划分C程序的预期行为时,仅适用标准的定义。
另一方面,这本书旨在教你C.它的目的是让你对C程序的行为有“感觉”。但为此,它可能很好地使用口语和不精确的语言,这是可以预料的。如果有好的评论,你不应该忽视这本书,但请记住,它不是标准的参考标准。
当C书采用C标准中使用的术语(例如副作用)并重新定义它们时,会出现这种混淆。
C中的副作用正如标准中的段落所定义的那样。
是的x = 1
因此是副作用。
是否规则如何编制分配是另一回事。也许,在书中,术语可观察效果会更好吗?
你的报价都包括副作用的定义:
C标准:
这是执行环境状态的变化
C Wikibook:
如果它修改了其范围之外的状态,或者与其调用函数或外部世界有可观察的交互。
那些定义了不同的东西,从而形成了混乱。虽然x = 1
是副作用(C标准),但它不是副作用(C Wikibook)。 C Wikibooks定义在C标准中称为可观察效果。
C标准倾向于对术语进行模糊和不完整的定义,这些术语不会特别努力排除该术语不适用的所有内容。例如,C11草案将对象定义为“执行环境中的数据存储区域,其内容可以表示值”。这类似于将“汽车”定义为“可以运送人的机动车辆”。这样的定义可以有利于区分汽车和马,但不能区分汽车与公共汽车,皮卡车或露营车。
通常使用的“副作用”的概念包含操作的直接范围之外的某些概念,并且这样的概念将与标准实际使用该术语的方式一致,如果人们认识到为了评估表达的目的或者子表达式,该操作的“范围”将限于该操作的结果或其寿命受其评估约束的事物。然而,如果标准试图以这种方式限制术语“副作用”,则必须定义副作用相对的“范围”。标准的作者不是这样做,而是使用更广泛的定义,并依靠读者将应用限制在有意义的地方。