__attribute__((const)) vs __attribute__((pure)) in GNU C
The difference is explained in the GCC manuals. Most notably a const
function may only use the arguments passed in and not any memory, whereas a pure
function can access memory too, under constraints:
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.
The __attribute__ ((pure))
means that the function has no side effects and the value returned depends on the arguments and the state of global variables. Therefore it is safe for the optimizer to elide some calls to it, if the arguments are the same, and the caller did not do anything to change the state of the globals in between the calls.
The __attribute__ ((const))
means that the return value is solely a function of the arguments, and if any of the arguments are pointers, then the pointers must not be dereferenced.
A const
function is always pure
.
Examples of const
functions would be the abs
functions from <stdlib.h>
and some mathematical functions from <math.h>
: sqrt
, exp
, etc. (Though they might be subject to rounding modes).
Examples of pure
but non-const functions would be such functions as strlen
- as it dereferences the pointer passed in.
From the documentation for the ARM compiler (which is based on 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.
So, TL;DR: __attribute__((const))
is the same as __attribute__((pure))
but without any access to global variables.