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

jsj*_*jsj 15 c c++ gcc pointers

有人可以澄清是否(和为什么)函数可以归因pureconst是否有一个指针参数.

根据GCC文件:

纯函数的一些常见示例是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");
Run Code Online (Sandbox Code Playgroud)

第二次调用memcmp的参数与第一次调用相同(指针指向同一地址),编译器如何知道不使用第一次调用的结果,如果memcmp是纯粹的?

在我的情况下,我想将数组传递给纯函数,并仅根据数组计算结果.有人向我保证这没关系,并且当数组中的值发生变化但地址没有变化时,我的函数将被正确调用.

Sha*_*our 3

关于pure,我们可以从《Implications of pure and Constant Functions》一文中看到,Pure意味着函数没有副作用,只依赖于参数。

\n\n

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

\n\n

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

\n\n

文章中的一个例子如下:

\n\n
int someimpurefunction(int a);\nint somepurefunction(int a)\n  __attribute__((pure));\n\nint testfunction(int a, int b, int c, int d) {\n\n  int res1 = someimpurefunction(a) ? someimpurefunction(a) : b;\n  int res2 = somepurefunction(a) ? somepurefunction(a) : c;\n  int res3 = a+b ? a+b : d;\n\n  return res1+res2+res3;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

它显示了生成的优化程序集,该程序集somepurefunction仅被调用一次,然后显示:

\n\n
\n

正如您所看到的,纯函数仅被调用一次,因为三元运算符内的两个引用是等效的,而另一个被调用了两次。这是因为在纯函数的两次调用之间,编译器已知的全局内存没有发生变化(函数本身无法更改它\xe2\x80\x93请注意,编译器永远不会考虑多线程) ,即使通过 -pthread 标志显式请求),同时允许非纯函数更改全局内存或使用 I/O 操作。

\n
\n\n

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

\n\n
x[1] = \'a\';\n
Run Code Online (Sandbox Code Playgroud)\n\n

它不能消除第二次调用,memcmp因为 by 指向的内存x已更改。

\n