关于GNU C中的gcc:__ attribute __((const))vs __attribute __((pure))

__attribute__((const)) vs __attribute__((pure)) in GNU C

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

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

VS

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


从ARM编译器的文档(基于gcc):

__attribute__((pure)) function attribute
Many functions have no effects except to return a value, and their return value depends only on the parameters and global variables. Functions of this kind can be subject to data flow analysis and might be eliminated.

__attribute__((const)) function attribute
Many functions examine only the arguments passed to them, and have no effects except for the return value. This is a much stricter class than __attribute__((pure)), because a function is not permitted to read global memory. If a function is known to operate only on its arguments then it can be subject to common sub-expression elimination and loop optimizations.

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


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

The pure attribute prohibits a function from modifying the state of the program that is observable by means other than inspecting the function’s return value. However, functions declared with the pure attribute can safely read any non-volatile objects, and modify the value of objects in a way that does not affect their return value or the observable state of the program.

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

__attribute__ ((const))表示返回值仅是参数的函数,如果任何参数是指针,则指针不得解除引用。

const函数始终为pure

const函数的示例是来自abs函数和来自的一些数学函数:sqrtexp等(尽管它们可能受到舍入模式的影响)。

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


请注意,如果函数传递了指针并检查该指针的上下文,则无法将其声明为const,即使传递的指针和指针上下文是const。这是对const的有用性的严重限制。

您可以使用结构在C中返回多个值,这样可以更轻松地使用pure。 (更常见的是使用指针返回操作数,但这会破坏pure的使用)。