2014-02-10 106 views
0

GCC docs常量GCC功能屬性和全局常量變量

許多功能不檢查任何值,除了他們的論點,並 除了有返回值沒有影響。基本上這只是 類比上面的純屬性稍微嚴格一些,因爲 函數不允許讀取全局內存。

我的問題是全局的const值是否算作全局內存。我認爲它確實如此,但是我明確表示標記爲不變的值可能會否定可能的優化,這似乎很奇怪。

例如:

int const ConstantModulusValue = 3; 

int foo(int value) { 
    return foo % ConstantModulusValue; 
} 

採用ConstantModulusValue,我的理解,意味着該函數不應該被打上const這又似乎很奇怪我。標記這個const有沒有一些危險,我沒有看到。?

回答

1

這些屬性允許編譯器知道在不知道它是如何實現的情況下忽略對函數的調用是安全的。

純屬性基本上說功能結果只取決於函數參數和全局狀態;另外,函數本身不會改變全局狀態。

如果你調用一個純函數兩次,它保證返回相同的結果;但是,如果您在調用之間改變全局可見狀態,則擔保不再成立。

const屬性更強,即使全局狀態發生了變化,函數仍應返回相同的結果;因此在更多情況下優化對const函數的冗餘調用是安全的。

如果您可以保證狀態不會發生變化,那麼讀取全局狀態不應該成爲問題(注意將全局標記爲常量並不總能保證這一點)。

作爲一個例子,考慮這樣的程序:

int foo(int) __attribute__((pure)); 
int bar(int) __attribute__((const)); 
void unknown(); 

int test1(int a) 
{ 
    int x = foo(a); 
    int y = foo(a); 
    return x + y; 
} 

int test2(int a) 
{ 
    int x = bar(a); 
    int y = bar(a); 
    return x + y; 
} 

int test3(int a) 
{ 
    int x = foo(a); 
    unknown(); 
    int y = foo(a); 
    return x + y; 
} 

int test4(int a) 
{ 
    int x = bar(a); 
    unknown(); 
    int y = bar(a); 
    return x + y; 
} 

用gcc 4.8.1編譯它和分析組件揭示TEST1()和TEST2()都只有一次調用相應的功能,然後乘以由2結果; test3()做3次調用 - 2次調用foo和1次調用未知; test4()對bar()進行調用,然後調用unknown(),並返回bar()的結果乘以2.

此行爲與上面的解釋匹配 - unknown()可以改變全局狀態,所以編譯器不能將額外的調用隱藏到foo(),但可以將額外的調用刪除到bar()。