局部变量赋值会产生副作用吗?

时间:2019-04-04 12:09:21

标签: c language-lawyer side-effects

来自 ISO / IEC 9899:201x 部分 5.1.2.3程序执行段落 2

  

访问易失性对象,修改对象,修改文件,   或调用执行任何这些操作的函数   效果,即执行状态的变化   环境。对表达式的评估通常包括   值计算和副作用的产生。价值计算   对于左值表达式,包括确定   指定对象。

该段说“修改对象” 是副作用。这意味着下面的代码:

int x; 
x = 1;

具有x = 1的副作用,因为它修改了对象x

但是,根据 C编程上的wikibooks

  

在C语言中,更一般地在计算机科学中,函数或表达式   如果它在其作用域之外修改状态,则被认为具有副作用   或与其调用函数或   外界。按照惯例,返回值会影响   调用函数,但这通常不被视为副作用。

     

一些副作用是:

     
      
  • 修改全局变量或静态变量
  •   
  • 修改函数参数
  •   
  • 将数据写入显示器或文件
  •   
  • 读取数据
  •   
  • 调用其他副作用函数
  •   

那么,谁是对的? x = 1真的有副作用吗?即使它不会改变范围之外的任何内容?还是我误解了标准?

4 个答案:

答案 0 :(得分:8)

  

那么,谁是对的?

关于标准中的定义,这就是标准。

  

x = 1真的有副作用吗?即使它不会改变范围之外的任何内容?

是的,您引用的标准段落也说了很多。

  

还是我误解了标准?

您已正确理解标准段落并将其应用于x = 1。但是您尝试将外部口语定义应用于标准文本是错误的。 C标准并不意味着向任何人传授C语言。它是一个正式文档,其唯一目的是定义C抽象机如何执行翻译后的程序。为此,它定义了一堆概念和术语。而已。当引用这些术语以判断C程序的预期行为时,仅适用标准的定义。

另一方面,这本书的目的是教您C语言。它的目的是使您对C程序的行为有一种“感觉”。但是为此,它很可能会使用口语和不精确的语言,这是可以预料的。如果书有很好的评价,则不要忽略这本书,但要记住,与标准不同,它不是规范性参考。

答案 1 :(得分:3)

当C书籍采用C标准中使用的术语(例如副作用)并重新定义它们时,就会产生这种混淆。

C中的副作用与标准中该段所定义的完全相同。

是的,x = 1是副作用。

好像规则是否将分配编译出去是另一回事。也许,在书中,可观察的效果一词会更好?

答案 2 :(得分:1)

两个引号都包含副作用的定义:

C标准:

  

是执行环境状态的变化

C Wikibook:

  

如果它修改了超出其范围的状态,或者与其调用函数或外界有可见的交互作用。

这些定义了不同的事物,因此造成了混乱。尽管x = 1是副作用(C标准),但不是副作用(C Wikibook)。 C Wikibooks的定义在C标准中称为可观察的效果

答案 3 :(得分:-1)

C标准倾向于给出模糊且不完整的术语定义,这些术语并没有做出特别的努力来排除该术语不适用的所有内容。例如,C11草案将对象定义为“执行环境中的数据存储区域,其内容可以表示值”。这类似于将“汽车”定义为“可以运输人员的机动车辆”。这样的定义可能有助于将汽车与马区分开,但不能将汽车与公共汽车,皮卡车或露营车区分开。

通常使用的“副作用”的概念涵盖了操作的直接范围之外的事物的概念,并且该概念与标准实际上使用术语的方式一致如果人们认识到出于评估表达式或子表达式的目的,则该操作的“范围”将限于该操作的结果或寿命与其评估绑定在一起的事物。但是,如果标准试图以这种方式限制术语“副作用”,则必须定义副作用相对于其的“范围”。该标准的作者并没有这样做,只是使用了更广泛的定义,而是依靠读者将应用限制在有意义的地方。