__attribute__((pure))
州的gcc文档:
除了返回值之外,许多函数都没有效果,它们的返回值仅取决于参数和/或全局变量。这样的函数可以像算术运算符那样经受公共子表达式消除和循环优化。应使用属性
pod update
声明这些函数。
仅依赖参数意味着什么?考虑:
pure
将struct Wrapper {
int i;
int get() const { return i; }
void set(int x) { i = x; }
};
标记为Wrapper::get()
成员函数是否有效?它仅取决于隐式pure
实例,但该数据可能会发生变化。
答案 0 :(得分:4)
将
Wrapper::get()
标记为pure
成员函数是否有效?它仅取决于隐式Wrapper
实例,但该数据可能会发生变化。
是的,Wrapper::get()
符合gcc pure
属性的要求。但请注意,__attribute__((pure))
并不代表纯粹的学术意义,即拥有参照透明度的属性。后者可以通过更严格的__attribute__((const))
:
__attribute__((const))
除了参数之外,许多函数都不会检查任何值 除了返回值之外没有任何效果。基本上这只是 比以下
pure
属性稍强一些的类,因为 函数不允许读取全局内存。请注意,该函数具有指针参数并检查数据 指向必须 not 声明
const
。同样,一个调用的函数 非const
函数通常不能是const
。它没有任何意义 使const
函数返回void
。
但由于Wrapper::get()
并不具备__attribute__((const))
隐含的引用透明度属性,因此无法将其标记为此类。
修改强>
关于函数的pure
- ness(在gcc' s意义上)的保证可以用于仅优化不包含对全局存储器的写入的代码块(并且,特别是,没有通过调用非pure
函数来穿插。例子:
struct Wrapper {
int i;
int get() const __attribute__((pure)) { return i; }
void set(int x) { i = x; }
};
long foo(Wrapper* w)
{
// w->get() can be computed once
return 2 * w->get() * w->get();
}
long bar(Wrapper* w)
{
// w->get() can be computed once (even though below code writes to memory,
// that memory is freshly allocated and cannot be accessed by w->get())
long result = 2;
result *= w->get();
result *= w->get();
return result;
}
long baz(Wrapper* w)
{
// both w->get()s must be evaluated, since non-pure code occurs between them
long result = 2;
result *= w->get();
std::cout << "Result after the first muliplication: " << result << std::endl;
result *= w->get();
return result;
}