The gcc documentation for __attribute__((pure))
states:
Many functions have no effects except the return value and their return value depends only on the parameters and/or global variables. Such a function can be subject to common subexpression elimination and loop optimization just as an arithmetic operator would be. These functions should be declared with the attribute
pure
.
What does it mean to only depend on the parameters? Consider:
struct Wrapper {
int i;
int get() const { return i; }
void set(int x) { i = x; }
};
Is it valid to label Wrapper::get()
as a pure
member function? It only depends on the implicit Wrapper
instance, but that data could change.
The const member functions are the functions which are declared as constant in the program. The object called by these functions cannot be modified. It is recommended to use const keyword so that accidental changes to object are avoided. A const member function can be called by any type of object.
Const member functions in C++ To make a member function constant, the keyword “const” is appended to the function prototype and also to the function definition header. Like member functions and member function arguments, the objects of a class can also be declared as const.
Declaring a member function with the const keyword specifies that the function is a "read-only" function that doesn't modify the object for which it's called. A constant member function can't modify any non-static data members or call any member functions that aren't constant.
A const member function is a member function that guarantees it will not modify the object or call any non-const member functions (as they may modify the object).
Is it valid to label
Wrapper::get()
as apure
member function? It only depends on the implicitWrapper
instance, but that data could change.
Yes, Wrapper::get()
meets the requirements of gcc's pure
attribute. Note, however, that __attribute__((pure))
doesn't mean pure in the academic sense, i.e. possessing the property of referential transparency. The latter can be communicated through a stricter __attribute__((const))
:
__attribute__((const))
Many functions do not examine any values except their arguments, and have no effects except the return value. Basically this is just slightly more strict class than the
pure
attribute below, since function is not allowed to read global memory.Note that a function that has pointer arguments and examines the data pointed to must not be declared
const
. Likewise, a function that calls a non-const
function usually must not beconst
. It does not make sense for aconst
function to returnvoid
.
But since Wrapper::get()
doesn't possess the property of referential transparency implied by __attribute__((const))
, it cannot be labeled as such.
EDIT
The guarantee about the pure
-ness (in gcc's sense) of a function can be used for optimizing only a block of code that doesn't contain writes to global memory (and, in particular, is not interspersed by calls to non-pure
functions). Examples:
struct Wrapper {
int i;
int get() const __attribute__((pure)) { return i; }
void set(int x) { i = x; }
};
long foo(Wrapper* w)
{
// w->get() can be computed once
return 2 * w->get() * w->get();
}
long bar(Wrapper* w)
{
// w->get() can be computed once (even though below code writes to memory,
// that memory is freshly allocated and cannot be accessed by w->get())
long result = 2;
result *= w->get();
result *= w->get();
return result;
}
long baz(Wrapper* w)
{
// both w->get()s must be evaluated, since non-pure code occurs between them
long result = 2;
result *= w->get();
std::cout << "Result after the first muliplication: " << result << std::endl;
result *= w->get();
return result;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With