如何在gcc中声明和定义纯函数?

sas*_*alm 6 c++ gcc

GCC具有pure和const属性,其中const实际上用于真正的纯函数(纯函数是幂等函数,也是无副作用的).

那么如何使用const-attribute声明和定义一个函数呢?

编辑:我对真正的纯函数感兴趣,使用const属性声明的函数,而不是使用pure-attribute声明的函数.

小智 6

例:

// Declaration:
int square (int x) __attribute__ ((const));
// Definition:
int __attribute__ ((const)) square (int x)
{ 
    return x*x; 
}
Run Code Online (Sandbox Code Playgroud)

所有属性的语法几乎相同:__attribute__ (( <attribute-name> )),或__attribute__ (( <attribute-name> ( <attribute-options> ) )).从您链接到的文档中引用:

关键字__attribute__允许您在进行声明时指定特殊属性.此关键字后面是双括号内的属性规范.

您链接到的文档中有一些示例可用于其他几个属性,包括pure:

int square (int) __attribute__ ((pure));
Run Code Online (Sandbox Code Playgroud)

所以你需要的,语法方面,使用const,pure改为const:

int square (int) __attribute__ ((const));
Run Code Online (Sandbox Code Playgroud)

正如评论中所指出的:如果你在定义中使用它,那么你需要放在__attribute__ ((const))一个不同的位置:

int square (int) __attribute__ ((const)) { ... } // doesn't work
int __attribute__ ((const)) square (int) { ... } // does work
Run Code Online (Sandbox Code Playgroud)

constpure属性是几乎唯一有用的,如果他们被应用到外部声明,所以这不应该是一个问题.如果定义可见,GCC通常是能够确定功能是否可以被视为const/ pure没有你的帮助.


mer*_*011 5

根据这篇文章,语法与@hvd所说的匹配:

int square (int) __attribute__ ((pure));
Run Code Online (Sandbox Code Playgroud)

但是,gcc在编译以下示例时,似乎没有强制执行不检查全局状态的属性.

#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;
}
Run Code Online (Sandbox Code Playgroud)

以下打印没有错误,代码运行和生成35.

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


gcc --version
gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
Run Code Online (Sandbox Code Playgroud)

更奇怪的是,gcc如果我们改变函数内部的全局状态并且因为它在全局状态中引起的更改而在每次调用中返回不同的值,也不关心.

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

40
45
50
Run Code Online (Sandbox Code Playgroud)

  • *"我开始怀疑该属性是否有任何作用."*hvd在他的回答中建议它可能仅在外部函数上使用时覆盖编译器分析...可能解释为什么它似乎没有为你的变异测试. (2认同)