這些屬性允許編譯器知道在不知道它是如何實現的情況下忽略對函數的調用是安全的。
純屬性基本上說功能結果只取決於函數參數和全局狀態;另外,函數本身不會改變全局狀態。
如果你調用一個純函數兩次,它保證返回相同的結果;但是,如果您在調用之間改變全局可見狀態,則擔保不再成立。
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()。