C中的副作用是什么?
What is a side effect in C?
C99条款5.1.2.3第2段,
Accessing a volatile object, modifying an object, modifying a file, or calling a function
that does any of those operations are all side effects, which are changes in the state of
the execution environment.
C 标准像上面那样定义了 副作用。但似乎C99并没有解释到底什么是accessing a volatile object, modifying an object, modifying a file(在clause 3中定义了什么是access, modify, object的定义。但是accessing a volatile how? modifying what object ?并修改文件的内容?)。
当我用 side effects 这个词搜索时,在 C99 中有一些例子。但我不能确定每个示例是否都属于访问 volatile 对象、修改对象和修改文件。
我读了 and Are side effects a good thing? 但还是很困惑。
我的问题是 C 标准是否明确描述了 副作用 的含义?它们是什么意思?
访问易失性对象意味着通过volatile-qualified左值读取volatile
限定对象/对象的值-标准说这些需要被评估“严格 根据抽象机的规则”。
修改对象意味着修改任何对象 - 修改任何内容都被视为副作用。示例:赋值运算符具有修改其赋值的变量的副作用!在下面的程序中。赋值运算符用于其副作用!
修改文件意味着写入文件、创建文件、删除文件等等 - 任何构成更改的内容。
这些类别的副作用示例:
void increment(int *p) {
(*p) ++; // side effect - assign a new value to the
// object pointed to by p
}
int a = 5;
volatile int b = 6;
if (b == 6) { // side-effect of accessing a volatile variable
a += b; // calculate a + b, and as a side effect assign a new
// value to a
}
increment(&a); // side effect - call a function that does
// one of the aforementioned operations
printf("%d\n", a); // side effect - change the state of an output stream
FILE *fp = fopen("foo", "w"); // side effect - create or truncate
fputc('!', fp); // side effect - modify file
fclose(fp);. // side effect - close the file, flush
remove("bar");. // side effect - remove file
有一类(更小的)编程语言称为纯函数式语言,例如 Haskell,其计算是 side-effect 免费的。 C 不是这样的语言之一。
My question is that does the C standard explicitly describe a meaning of side effects?
你引用的C标准(C 1999 5.1.2.3 2,C 2018同)中的那句话明确描述了side effects的含义。这些将在下面进一步解释。
修改对象
修改对象被理解为包括更新表示对象的存储字节的内容。我相信他们的完整列表是:
- 简单赋值(
=
)和复合赋值(*=
,/=
%=
,+=
,-=
,<<=
、>>=
、&=
、^=
和 |=
)。
- 递增和递减运算符(
++
和 --
),包括前缀和后缀。
- 初始化包含在其定义中的对象。
- 指定改变对象的库例程,例如
memcpy
.
访问可变对象
“访问”在 C 2018 3.1 中定义为“⟨execution-time action⟩ to read or modified the value of an object”。如果 x
是 volatile int
,则在表达式中使用 x
的值访问它(当计算表达式时),因为它读取 x
的值。您可以更具体地遵循这一点,因为 6.3.2.1 2 告诉我们在表达式中使用 x
会导致采用 x
的值:
Except when it is the operand of the sizeof
operator, the unary &
operator, the ++
operator, the --
operator, or the left operand of the .
operator or an assignment operator, an lvalue that does not have array type is converted to the value stored in the designated object (and is no longer an lvalue); this is called lvalue conversion.
所以表达式中的 x
本身只是对象 x
的指定,被转换为存储在 x
中的值,这意味着存储从内存中读取值。即x
.
的访问
修改可变对象与修改任何对象相同,如上所述。
修改文件
通过第 7.21 条(“Input/output <stdio.h>
”)中定义的例程修改文件。
C99条款5.1.2.3第2段,
Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment.
C 标准像上面那样定义了 副作用。但似乎C99并没有解释到底什么是accessing a volatile object, modifying an object, modifying a file(在clause 3中定义了什么是access, modify, object的定义。但是accessing a volatile how? modifying what object ?并修改文件的内容?)。
当我用 side effects 这个词搜索时,在 C99 中有一些例子。但我不能确定每个示例是否都属于访问 volatile 对象、修改对象和修改文件。
我读了
我的问题是 C 标准是否明确描述了 副作用 的含义?它们是什么意思?
访问易失性对象意味着通过volatile-qualified左值读取volatile
限定对象/对象的值-标准说这些需要被评估“严格 根据抽象机的规则”。
修改对象意味着修改任何对象 - 修改任何内容都被视为副作用。示例:赋值运算符具有修改其赋值的变量的副作用!在下面的程序中。赋值运算符用于其副作用!
修改文件意味着写入文件、创建文件、删除文件等等 - 任何构成更改的内容。
这些类别的副作用示例:
void increment(int *p) {
(*p) ++; // side effect - assign a new value to the
// object pointed to by p
}
int a = 5;
volatile int b = 6;
if (b == 6) { // side-effect of accessing a volatile variable
a += b; // calculate a + b, and as a side effect assign a new
// value to a
}
increment(&a); // side effect - call a function that does
// one of the aforementioned operations
printf("%d\n", a); // side effect - change the state of an output stream
FILE *fp = fopen("foo", "w"); // side effect - create or truncate
fputc('!', fp); // side effect - modify file
fclose(fp);. // side effect - close the file, flush
remove("bar");. // side effect - remove file
有一类(更小的)编程语言称为纯函数式语言,例如 Haskell,其计算是 side-effect 免费的。 C 不是这样的语言之一。
My question is that does the C standard explicitly describe a meaning of side effects?
你引用的C标准(C 1999 5.1.2.3 2,C 2018同)中的那句话明确描述了side effects的含义。这些将在下面进一步解释。
修改对象
修改对象被理解为包括更新表示对象的存储字节的内容。我相信他们的完整列表是:
- 简单赋值(
=
)和复合赋值(*=
,/=
%=
,+=
,-=
,<<=
、>>=
、&=
、^=
和|=
)。 - 递增和递减运算符(
++
和--
),包括前缀和后缀。 - 初始化包含在其定义中的对象。
- 指定改变对象的库例程,例如
memcpy
.
访问可变对象
“访问”在 C 2018 3.1 中定义为“⟨execution-time action⟩ to read or modified the value of an object”。如果 x
是 volatile int
,则在表达式中使用 x
的值访问它(当计算表达式时),因为它读取 x
的值。您可以更具体地遵循这一点,因为 6.3.2.1 2 告诉我们在表达式中使用 x
会导致采用 x
的值:
Except when it is the operand of the
sizeof
operator, the unary&
operator, the++
operator, the--
operator, or the left operand of the.
operator or an assignment operator, an lvalue that does not have array type is converted to the value stored in the designated object (and is no longer an lvalue); this is called lvalue conversion.
所以表达式中的 x
本身只是对象 x
的指定,被转换为存储在 x
中的值,这意味着存储从内存中读取值。即x
.
修改可变对象与修改任何对象相同,如上所述。
修改文件
通过第 7.21 条(“Input/output <stdio.h>
”)中定义的例程修改文件。