using just standard C++11:
namespace g{ int x; }
constexpr int foo()
{
//return g::x = 42; Nah, not constant
return 42; // OK
}
int main()
{}
here's another example:
constexpr int foo( int blah = 0 )
{
return blah + 42; // OK
}
int main( int argc, char** )
{
int bah[foo(2)]; // Very constant.
int const troll = foo( argc ); // Very non-constant.
}
The meaning of GCC's __attribute__( const )
is documented in the GNU compiler docs as …
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.
One may take that to mean that the function result should only depend on the arguments, and that the function should have no side effects.
This allows a more general class of functions than C++11 constexpr
, which makes the function inline
, restricts arguments and function result to literal types, and restricts the "active" statements of the function body to a single return
statement, where (C++11 §7.1.5/3)
— every constructor call and implicit conversion used in initializing the return value (6.6.3, 8.5) shall be one of those allowed in a constant expression (5.19)
As an example, it is difficult (I would think not impossible, but difficult) to make a constexpr
sin
function.
But the purity of the result matters only to two parties:
When known to be pure, the compiler can elide calls with known results.
This is mostly an optimization of macro-generated code. Replace macros with inline
functions to avoid silly generation of identical sub-expressions.
When known to be pure, a programmer can remove a call entirely.
This is just a matter of proper documentation. :-)
So instead of looking for a way to express the purity of e.g. sin
in the language, I suggest just avoid code generation via macros, and document pure functions as such.
And use constexpr
for the functions where it's practically possible (unfortunately, as of Dec. 2012 the latest Visual C++ compiler doesn't yet support constexpr
).
There is a previous SO question about the relationship between pure and constexpr
. Mainly, every constexpr
function is pure, but not vice versa.