2016-11-23 41 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