接受指针参数的GCC纯/const函数
GCC pure/const functions that accept a pointer argument
有人可以澄清是否(以及为什么)一个函数可以归因于pure
或const
,如果它有一个指针参数
根据GCC文档:
纯函数的一些常见示例是strlen或memcmp。
一个纯函数的要点是,它只需要调用一次相同的参数,也就是说,结果可以缓存,如果编译器认为它适合这样做,但是这是如何工作的memcmp?
例如:char *x = calloc(1, 8);
char *y = calloc(1, 8);
if (memcmp(x, y, 8) > 0)
printf("x > yn");
x[1] = 'a';
if (memcmp(x, y, 8) > 0)
printf("x > yn");
第二次调用memcmp的参数与第一次相同(指针指向相同的地址),编译器如何知道不使用第一次调用的结果,如果memcmp
是纯的?
在我的例子中,我想将一个数组传递给一个纯函数,并仅基于数组计算结果。有人向我保证,这是可以的,当数组中的值改变,但地址没有,我的函数将被正确调用。
如果我正确理解了文档,那么pure
函数可以依赖于内存的值,其中编译器知道内存何时更改。而且,pure
函数不能改变程序的状态,比如全局变量,它只产生一个返回值。
在您的示例代码中,memcmp
可以是pure
函数。编译器看到在调用memcmp
之间内存被改变了,并且不能在第二次调用时重用第一次调用的结果。
memcmp
可以将而不是声明为const
函数,因为它依赖于内存中的数据。如果是const
,编译器可以应用更激进的优化。
因此,将要实现的函数声明为pure
(而不是const
)似乎是安全的。
关于纯函数,我们可以从纯函数和常量函数的含义一文中看到,纯函数意味着函数没有副作用,只依赖于参数。
因此,如果编译器可以确定参数是相同的,并且在后续调用之间内存没有变化,那么它可以消除对纯函数的后续调用,因为它知道纯函数没有副作用。
这意味着编译器必须进行分析,以确定纯函数的实参是否被修改,然后才能决定取消对纯函数的相同实参的后续调用。
文章中的一个例子如下:
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
只被调用了一次,然后说:
如您所见,纯函数只被调用一次,因为三元操作符中的两个引用是等价的,而另一个则被调用两次。这是因为在纯函数的两次调用之间编译器不知道全局内存的变化(函数本身不能改变它 -注意编译器永远不会考虑多线程,即使通过-pthread标志显式请求),而非纯函数允许改变全局内存或使用I/O操作。
这个逻辑也适用于指针,所以如果编译器可以证明指向指针的内存没有被修改,那么它可以消除对纯函数的调用,所以在你的情况下,当编译器看到:
x[1] = 'a';
它不能消除对memcmp
的第二次调用,因为x
所指向的内存已经改变。
- 在 const 函数中通过引用和指针返回之间的区别
- 使用 std::string () const 函数启动线程或未来
- 如果我在 const 函数上使用指针,我可以返回什么?
- 为什么 const 函数返回左值而不是右值?
- 当我调用 main 中使用 const 对象的 const 函数时,不断出现错误
- 在 const 对象上调用非 const 函数
- 析构函数是否可以在 const 对象上调用非 const 函数
- C/C++ 如何在一次函数调用中交出 const 函数指针或简单指针
- 为什么我可以在C 11中使用const函数修改类
- 防止const函数被调用非const对象
- 如果C 中的支架重载运算符被声明为const函数
- C++:防止在 const 函数中更改指针的值
- 从const函数返回非const属性参考
- 调用指针参数从const函数指向的对象的操作员
- 在const函数中调用非CONST成员的非const函数
- 无法将 const 数据类型传递到非 const 函数中
- 这是检查 const 函数(如果是否创建某些内容)的更好方法
- 在 const 函数中从地图中未经选中读取
- 编译器不会为 "const" 和"not-const"函数给出不明确的错误吗
- 通过const函数中的参数索引返回std :: map的值