简体   繁体   中英

How to declare and define a pure function in gcc?

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

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

Edit: I'm interested in the real pure functions, the ones declared with the const-attribute, not the ones declared with the pure-attribute.

Example:

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

The syntax for all attributes is pretty much the same: __attribute__ (( <attribute-name> )) , or __attribute__ (( <attribute-name> ( <attribute-options> ) )) . Quoting from the documentation you link to:

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

There are examples in the documentation you link to for several other attributes, including pure :

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

so all you need, syntax-wise, to use const , is change pure to const :

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

As pointed out in the comments: if you're using it in a definition, then you need to put __attribute__ ((const)) in a different location:

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

but the const and pure attributes are pretty much only useful if they are applied to external declarations, so that shouldn't be a problem. If the definition is visible, GCC is usually able to determine whether the function can be treated as const / pure without your help.

According this this article , the syntax matches with what @hvd says:

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

However, it seems that gcc does not enforce the property of not examining global state when I compile 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;
}

The following prints no errors, and the code runs and produces 35 .

gcc -Wall -Werror -pedantic -O3 Pure.c


gcc --version
gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1

Even more curiously, gcc also does not care if we mutate the global state inside the function and return a different value on each call because of a change 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

Starting with C++11 one can use an attribute specifier sequence to specify such attributes. For example:

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

Also, starting with C++17 all attributes unknown to a compiler are ignored without causing an error. So the code above becomes portable between different compilers and platforms.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM