在GNU C中__attribute__((const))
和__attribute__((pure))
有什么区别?
__attribute__((const)) int f() {
/* ... */
return 4;
}
VS
__attribute__((pure)) int f() {
/* ... */
return 4;
}
差异在GCC manuals中解释。最值得注意的是const
函数可能只使用传入的参数而不是任何内存,而pure
函数也可以在约束条件下访问内存:
pure属性禁止函数通过检查函数返回值以外的方式修改可观察的程序状态。但是,使用pure属性声明的函数可以安全地读取任何非易失性对象,并以不影响其返回值或程序的可观察状态的方式修改对象的值。
__attribute__ ((pure))
意味着该函数没有副作用,返回的值取决于参数和全局变量的状态。因此,如果参数相同,优化器可以安全地忽略对它的一些调用,并且调用者没有做任何事情来改变调用之间的全局变量的状态。
__attribute__ ((const))
意味着返回值只是参数的函数,如果任何参数是指针,那么指针不能被解引用。
const
功能总是pure
。
const
函数的例子是来自abs
的<stdlib.h>
函数和来自<math.h>
的一些数学函数:sqrt
,exp
等(尽管它们可能受到舍入模式的影响)。
pure
但非const函数的例子是strlen
这样的函数 - 因为它取消引用传入的指针。
来自documentation for the ARM compiler(基于gcc):
__attribute__((pure))
函数属性 除了返回值之外,许多函数都没有效果,它们的返回值仅取决于参数和全局变量。这种功能可以进行数据流分析,可以消除。
__attribute__((const))
函数属性 许多函数只检查传递给它们的参数,除了返回值之外没有任何效果。这是一个比__attribute__((pure))
更严格的类,因为不允许函数读取全局内存。如果已知函数仅对其参数进行操作,则可以对常见的子表达式消除和循环优化进行处理。
因此,TL; DR:__attribute__((const))
与__attribute__((pure))
相同,但无法访问全局变量。
请注意,如果函数传递了指针并检查该指针的上下文,则无法将其声明为const
,即使传递的指针和指针上下文是const
也是如此。这是对const
有用性的严重限制。
您可以使用结构在C中返回多个值,这样可以更轻松地使用pure
。 (更常见的是使用指针返回操作数,但这会破坏pure
的使用)。