C++ 接受指针参数的GCC pure/const函数

C++ 接受指针参数的GCC pure/const函数,c++,c,pointers,gcc,C++,C,Pointers,Gcc,有人能澄清一下,如果一个函数有指针参数,它是否(以及为什么)可以归属于pure或const 根据报告: 纯函数的一些常见示例是strlen或memcmp 纯函数的全部要点是,对于相同的参数,只需调用一次,即如果编译器认为适合,可以缓存结果,但这对memcmp如何起作用 例如: char *x = calloc(1, 8); char *y = calloc(1, 8); if (memcmp(x, y, 8) > 0) printf("x > y\n"); x[1] =

有人能澄清一下,如果一个函数有指针参数,它是否(以及为什么)可以归属于
pure
const

根据报告:

纯函数的一些常见示例是strlen或memcmp

纯函数的全部要点是,对于相同的参数,只需调用一次,即如果编译器认为适合,可以缓存结果,但这对memcmp如何起作用

例如:

char *x = calloc(1, 8);
char *y = calloc(1, 8);

if (memcmp(x, y, 8) > 0)
    printf("x > y\n");

x[1] = 'a';
if (memcmp(x, y, 8) > 0)
    printf("x > y\n");
第二次调用memcmp的参数与第一次调用相同(指针指向相同的地址),如果
memcmp
是纯的,编译器如何知道不使用第一次调用的结果


在我的例子中,我想把一个数组传递给一个纯函数,然后只根据数组计算结果。有人向我保证这没问题,当数组中的值发生变化但地址没有变化时,我的函数将被正确调用。

关于pure,我们可以从文章中看到,pure意味着函数没有副作用,只取决于参数

因此,如果编译器可以确定参数是相同的,并且在后续调用之间内存没有改变,那么它可以消除对pure函数的后续调用,因为它知道pure函数没有副作用

这意味着编译器必须进行分析,才能确定pure函数的参数是否已被修改,然后才能决定消除对相同参数的pure函数的后续调用

文章中的一个例子如下:

int someimpurefunction(int a);
int somepurefunction(int a)
  __attribute__((pure));

int testfunction(int a, int b, int c, int d) {

  int res1 = someimpurefunction(a) ? someimpurefunction(a) : b;
  int res2 = somepurefunction(a) ? somepurefunction(a) : c;
  int res3 = a+b ? a+b : d;

  return res1+res2+res3;
}
它显示了生成的优化程序集,显示只调用了一次
somepurefunction
,然后说:

如您所见,pure函数只调用一次,因为三元运算符中的两个引用是等效的,而另一个调用两次这是因为在pure函数的两次调用之间,编译器所知道的全局内存没有变化(函数本身无法改变它–请注意,编译器永远不会考虑多线程,即使通过-pthread标志显式请求时也是如此),而非纯函数允许更改全局内存或使用I/O操作

此逻辑也适用于指针,因此如果编译器可以证明指向指针的内存未被修改,则可以消除对pure函数的调用,因此在您的情况下,当编译器看到:

x[1] = 'a';

它无法消除对
memcmp
的第二次调用,因为
x
指向的内存已更改。

如果我正确理解了文档,则
函数可以依赖于内存值,编译器知道内存何时更改。此外,
函数不能更改程序的状态,例如全局变量,它只生成一个返回值

在示例代码中,
memcmp
可以是一个
纯函数。编译器发现在调用
memcmp
之间内存发生了变化,无法将第一次调用的结果重新用于第二次调用

另一方面,
memcmp
可以not声明为
const
函数,因为它依赖于内存中的数据。 如果是
const
,编译器可以应用更积极的优化


出于这个原因,将要实现的函数声明为
pure
(而不是
const
)似乎是安全的。

感谢文章链接,很有趣。但我的问题是关于纯函数的指针参数。那么,如果8和1在编译时未知,会发生什么呢?例如,它们是可变的?@kata:如果编译器无法证明内存没有发生变异,那么它必须假设内存可能发生了变异。所以它不会执行(不安全的)优化。好了,现在清楚了。这个答案应该被接受:)如果你在结尾添加一个小部分解释相同的逻辑适用于指针,我会接受这个答案(我只是想确保通过谷歌登陆这里的人,而不是阅读这些评论的人,觉得他们的问题得到了回答)