GNU C中的__attribute __((const))vs __attribute __((pure))

时间:2015-03-18 09:05:56

标签: c gcc attributes const gnu

GNU C中__attribute__((const))__attribute__((pure))之间有什么区别?

__attribute__((const)) int f() {
    /* ... */
    return 4;
}

VS

__attribute__((pure)) int f() {
    /* ... */
    return 4;
}

3 个答案:

答案 0 :(得分:32)

来自documentation for the ARM compiler(基于gcc):

  

__attribute__((pure))功能属性
  除了返回值之外,许多函数都没有效果,它们的返回值仅取决于参数和全局变量。这类功能可以进行数据流分析,也可以消除。

     

__attribute__((const))功能属性
  许多函数只检查传递给它们的参数,除了返回值之外没有任何效果。这是一个比__attribute__((pure))更严格的类,因为不允许函数读取全局内存。如果已知函数仅对其参数进行操作,那么它可以进行常见的子表达式消除和循环优化。

因此,TL; DR:__attribute__((const))__attribute__((pure))相同,但无法访问全局变量。

答案 1 :(得分:13)

差异在GCC manuals中解释。最值得注意的是const函数只能使用传入的参数而不能使用任何内存,而pure函数也可以在约束条件下访问内存:

  

pure属性禁止函数通过检查函数返回值以外的方式修改可观察的程序状态。但是,使用pure属性声明的函数可以安全地读取任何非易失性对象,并以不影响其返回值或程序的可观察状态的方式修改对象的值。

__attribute__ ((pure))表示该函数没有副作用,返回的值取决于参数和全局变量的状态。因此,如果参数相同,优化器可以安全地忽略对它的一些调用,并且调用者没有做任何事情来改变调用之间的全局变量的状态

__attribute__ ((const))表示返回值只是参数的函数,而如果任何参数是指针,那么指针不能被解除引用

const函数始终为pure

const函数的示例包括来自abs的{​​{1}}函数和来自<stdlib.h>的一些数学函数:<math.h>sqrt等(虽然他们可能会受到舍入模式的影响)。

exp但非const函数的例子是pure这样的函数 - 因为它取消引用传入的指针。

答案 2 :(得分:0)

请注意,如果函数传递了一个指针并检查了该指针的上下文,即使传递的指针和指针上下文是const,也不能将其声明为const。这严重限制了const的用途。

您可以使用结构在C中返回多个值,这使得使用pure更容易。 (使用指针返回操作数更为典型,但这会中断pure的使用。)