jsj*_*jsj 15 c c++ gcc pointers
有人可以澄清是否(和为什么)函数可以归因pure或const是否有一个指针参数.
根据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是纯粹的?
在我的情况下,我想将数组传递给纯函数,并仅根据数组计算结果.有人向我保证这没关系,并且当数组中的值发生变化但地址没有变化时,我的函数将被正确调用.
关于pure,我们可以从《Implications of pure and Constant Functions》一文中看到,Pure意味着函数没有副作用,只依赖于参数。
\n\n因此,如果编译器可以确定参数相同,并且后续调用之间的内存没有更改,则可以消除对纯函数的后续调用,因为它知道纯函数没有副作用。
\n\n这意味着编译器必须进行分析,以确定纯函数的参数是否可以修改,然后才能决定消除对相同参数的纯函数的后续调用。
\n\n文章中的一个例子如下:
\n\nint 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}\nRun Code Online (Sandbox Code Playgroud)\n\n它显示了生成的优化程序集,该程序集somepurefunction仅被调用一次,然后显示:
\n\n\n正如您所看到的,纯函数仅被调用一次,因为三元运算符内的两个引用是等效的,而另一个被调用了两次。这是因为在纯函数的两次调用之间,编译器已知的全局内存没有发生变化(函数本身无法更改它\xe2\x80\x93请注意,编译器永远不会考虑多线程) ,即使通过 -pthread 标志显式请求),同时允许非纯函数更改全局内存或使用 I/O 操作。
\n
此逻辑也适用于指针,因此如果编译器可以证明指向指针的内存未被修改,那么它可以消除对纯函数的调用,因此在您的情况下,当编译器看到:
\n\nx[1] = \'a\';\nRun Code Online (Sandbox Code Playgroud)\n\n它不能消除第二次调用,memcmp因为 by 指向的内存x已更改。