How to declare and define a pure function in gcc?

GCC has the attributes pure and const, where const is actually used for real pure functions (purely for idempotent functions, which are also side effects ).

So how do I declare and define a function using a const attribute?

Edit: I'm interested in real pure functions declared using the const attribute, not those declared using the pure attribute.

+6
source share
3 answers

Example:

// Declaration: int square (int x) __attribute__ ((const)); // Definition: int __attribute__ ((const)) square (int x) { return x*x; } 

The syntax for all attributes is approximately the same: __attribute__ (( <attribute-name> )) or __attribute__ (( <attribute-name> ( <attribute-options> ) )) . A quote from the documentation you are referring to:

The __attribute__ keyword allows you to specify special attributes when creating an ad. This keyword is followed by an attribute specification inside double parentheses.

The documentation you refer to uses several other attributes, including pure :

 int square (int) __attribute__ ((pure)); 

so all you need to syntactically use const is to change pure to const :

 int square (int) __attribute__ ((const)); 

As stated in the comments: if you use it in the definition, you need to put __attribute__ ((const)) in another place:

 int square (int) __attribute__ ((const)) { ... } // doesn't work int __attribute__ ((const)) square (int) { ... } // does work 

but the const and pure attributes are pretty much useful if they apply to external declarations, so this should not be a problem. If the definition is visible, GCC can usually determine if a function can be processed as const / pure without your help.

+6
source

As per this article, the syntax is consistent with what @hvd says:

 int square (int) __attribute__ ((pure)); 

However, it seems that gcc does not use the property not to investigate global state when compiling the following example.

 #include <stdio.h> int square (int) __attribute__ ((pure)); int outerX = 7; int square(int x) { return outerX * x; } int main(){ printf("%d\n", square(5)); return 0; } 

Below errors are not printed, and the code is launched and produces 35 .

 gcc -Wall -Werror -pedantic -O3 Pure.c gcc --version gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 

Even more curious, gcc also does not care if we mutate the global state inside the function and return a different value for each call due to the change that it caused in the global state.

 #include <stdio.h> int square (int) __attribute__ ((pure)); int outerX = 7; int square(int x) { outerX++; return outerX * x; } int main(){ printf("%d\n", square(5)); printf("%d\n", square(5)); printf("%d\n", square(5)); return 0; } 

Output:

 40 45 50 
+5
source

Starting with C ++ 11, you can use a sequence of attribute specifiers to specify such attributes. For instance:

 [[ gnu::const ]] int square (int x) { return x * x; } 

In addition, starting with C ++ 17, all attributes unknown to the compiler are ignored without an error. Thus, the above code becomes portable between different compilers and platforms.

+1
source

Source: https://habr.com/ru/post/982194/


All Articles