在GNU C中,__attribute__((const))
和__attribute__((pure))
有什么区别?
__attribute__((const)) int f() {
/* ... */
return 4;
}
对比
__attribute__((pure)) int f() {
/* ... */
return 4;
}
在GNU C中,__attribute__((const))
和__attribute__((pure))
有什么区别?
__attribute__((const)) int f() {
/* ... */
return 4;
}
对比
__attribute__((pure)) int f() {
/* ... */
return 4;
}
根据基于gcc的ARM编译器文档:
__attribute__((pure))
函数属性
许多函数除返回值外没有其他影响,它们的返回值仅取决于参数和全局变量。这些函数可能会接受数据流分析并被消除。
__attribute__((const))
函数属性
许多函数只检查其传递的参数,并且除了返回值之外没有其他影响。这是比__attribute__((pure))
更严格的类别,因为不允许函数读取全局内存。如果已知函数仅对其参数进行操作,则可以将其用于公共子表达式消除和循环优化。
因此,简而言之:__attribute__((const))
与__attribute__((pure))
相同,但不能访问全局变量。
需要注意的是,如果一个函数有指针参数并且检查所指向的数据,则不能声明为const。
- origoconst
函数只能使用传递进来的参数而不能使用任何内存,而pure
函数也可以访问内存,但有限制:
pure
属性禁止函数修改程序状态,这种状态可以通过除了检查函数的返回值之外的方式来观察到。但是,使用pure
属性声明的函数可以安全地读取任何非易失性对象,并以不影响其返回值或程序的可观测状态的方式修改对象的值。
__attribute__ ((pure))
意味着该函数没有副作用,返回的值取决于参数和全局变量的状态。因此,如果参数相同且调用者没有对全局状态进行更改,则优化器可以省略其中一些调用。
__attribute__ ((const))
意味着返回值完全是由参数决定的,并且如果任何参数是指针,则不能对指针进行间接引用。
const
函数始终是pure
函数。
<stdlib.h>
中的abs
函数和<math.h>
中的一些数学函数如sqrt
, exp
等都是const
函数的例子(尽管它们可能受到舍入模式的影响)。
strlen
等函数因为对传递进来的指针进行了间接引用,所以是pure
但非函数的例子。