2016-11-23 43 views
14

gcc的文档__attribute__((pure))状态:诠释一个const成员函数与纯属性

许多功能,除了有返回值没有影响,它们的返回值只取决于参数和/或全局变量。这样的函数可以像算术运算符那样经受常见的子表达式消除和循环优化。这些函数应该用属性pure来声明。

仅仅依赖于参数是什么意思?试想一下:

struct Wrapper { 
    int i; 

    int get() const { return i; } 
    void set(int x) { i = x; } 
}; 

是否有效标记Wrapper::get()pure成员函数?它仅取决于隐含的Wrapper实例,但该数据可能会更改。

+1

本文可能与http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0078r0相关。pdf – Danh

+1

隐含对象(this)参数仍然是一个参数。语法无关紧要。如果foo(x)或x.foo()或其他什么都调用。 –

+0

@Danh从这篇论文中不完全清楚这个问题的答案是什么。这似乎有点不置可否。 – Barry

回答

4

Wrapper::get()标记为pure成员函数是否有效?它仅取决于隐含的Wrapper实例,但该数据可能会更改。

是的,Wrapper::get()符合gcc的pure属性的要求。然而,请注意,__attribute__((pure))并不意味着在学术意义上是纯粹的,即具有参照透明性。后者可以通过更严格的__attribute__((const))送交:

__attribute__((const))

很多函数不检查除它们的参数的任何值,并 除了有返回值没有影响。基本上这只是 稍差一些,比pure属性稍差一些,因为 函数不允许读取全局内存。

注意,有指针参数,且检查 指出,必须声明const数据的功能。同样,调用 非const函数的函数通常不能是const。对于const函数, 没有意义返回void

但由于Wrapper::get()不具备通过__attribute__((const))隐含引用透明的性质,它不能被打成这样。

编辑

功能关于pure -ness担保(在GCC的意义上),可用于优化只是一个代码块不包含写入全局存储器(和,特别是,不穿插到对非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; 
} 
+0

你确定'__attribute __((const))'?是不是隐式的'this'这个函数的指针参数? – Barry

+0

@Barry查看更新回答 – Leon

+0

我不确定添加术语“参考透明度”有帮助。这个词甚至有一个确定的含义吗? 'strlen()'不是透明的? – Barry