Pure functions in C ++ 11

Can one of C ++ 11 somehow in gcc mark a function (not a class method) as const , indicating that it is clean and does not use global memory, but only its arguments?

I tried gcc __attribute__((const)) and that is exactly what I want. But when the global memory fails in the function, no compile-time error occurs.

Change 1

Be careful . I mean pure functions. Not permanent functions . The GCC attribute is a bit confusing. Pure functions use only their arguments.

+7
source share
3 answers

Are you looking for constexpr ? This tells the compiler that the function can be evaluated at compile time. The constexpr function must have a literal return and parameter types, and the body can only contain static statements, typedefs, using declarations and directives and one return statement. The constexpr function can be called in constant expression.

 constexpr int add(int a, int b) { return a + b; } int x[add(3, 6)]; 

Looking at the __atribute__((const)) value, the answer is no, you cannot do it with standard C ++. Using constexpr will lead to the same effect, but only to a much more limited set of functions. However, nothing prevents the compiler from doing these optimizations on its own, however, if the compiled program behaves the same (as-if rule).

+4
source

Because a lot has been said here, let's forget about meta-programming at the moment, which is purely functional in any case and off topic.

Secondly, I suppose that the OP means pure as a statement to be checked by the compiler. GCC pure attribute is the opposite, a way for the encoder to help the compiler.

While the answer to the OP question is NO, it’s very interesting to read the history of attempts to enter a clean keyword (or unclean and let the default be clean).

The d-lang community quickly found out that the meaning of "pure" is not clear. Logging should not result in a dirty function. Pure functions allow variables that cannot invoke a function call. Equal return values ​​with different addresses should not be considered unclean. But D goes even further than stretching purity.

So, the d-lang community coined the terms "poorly clean" and "very clean." But later disputes showed that the weak and strong are not black and white, but gray areas. see cleanliness in D

Rust introduced the keyword β€œclean” early on; and they dropped it because of its complexity. see cleanliness in Rust .

Among the great benefits of a β€œpure” keyword is an ugly consequence. A template function can be pure or independent of its type parameters. This can explode the number of template instances. These instances can exist temporarily only in the compiler and not get into the executable file, but they can still break the compilation time.

The syntax highlighting editor can be useful here without changing the language. Optimization of C ++ compilers really explains the purity of the function, they just do not guarantee the trick of all cases.

I am sad that this feature has low priority. This simplifies the discussion of code. I would even argue that this will improve software development, as it encourages programmers to think differently.

+1
source

using only standard C ++ 11:

 namespace g{ int x; } constexpr int foo() { //return g::x = 42; Nah, not constant return 42; // OK } int main() {} 

here is 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 GCC __attribute__( const ) value is documented in the GNU compiler documents as & hellip;

Many functions do not check values ​​other than their arguments, and have no effects other than the return value. Basically, this is a slightly more strict class than the pure attribute below, since functions are not allowed to read global memory.

We can assume that the result of the function should depend only on the arguments and that the function should not have side effects.

This allows you to use a more general class of functions than C ++ 11 constexpr , which makes the inline function, limits the arguments and result of the function to literals and limits the "active" body functions of the single return function, where (C ++ 11 Β§7.1.5 / 3)

- each call to the constructor and the implicit conversion used to initialize the return value (6.6.3, 8.5) must be one of the allowed in the constant expression (5.19)

As an example, it is difficult (I think not impossible, but difficult) to make the constexpr sin function.

But the purity of the result matters only for two parties:

  • When it is known that it is clean, the compiler can overcome challenges with known results.
    This is mainly an optimization of macro-generated code. Replace macros with inline functions to avoid stupidly generating identical subexpressions.

  • When it is known that it is clean, the programmer can completely remove the call.
    This is just a matter of proper documentation. :-)

Thus, instead of looking for a way to express purity, for example. sin in the language, I suggest simply avoiding code generation through macros, as well as writing pure functions as such.

And use constexpr for functions where it is practically possible (unfortunately, as of December 2012, the last Visual C ++ compiler does not yet support constexpr ).


There is a previous question about the relationship between pure and constexpr . Basically, every constexpr function is pure, but not vice versa.

0
source

All Articles