C++中將一個成員函數定義為const的會有助於提高性能嗎?

比如string func() const {};
這樣會有助於提高編譯的速度或者執行時的速度嗎?請分析一下。謝謝。


沒有任何作用。就算你定義了const,編譯器也無法保證不會有其他地方把const強轉為普通指針並修改其內容。所以編譯器不會因為const而去優化某些代碼。

另外一方面,如果一個東西沒有定義const但實際上編譯器能知道沒有任何地方修改了這個變數,那麼也會按照常數進行優化。

const只有軟體工程上的意義,幫助程序員檢查程序中潛在的錯誤。僅此而已。


不行,因為有mutable這樣的東西存在,當然也有 @vczh說的const_cast,這就造成了編譯器沒有辦法確認const聲明的一定是肯定不能改的,而如果是指針的話,可以考慮C99引入的restrict(雖然並未被納入C++標準,但是幾乎所有的C++編譯器都支持在C++使用這個關鍵字,但是也許形式不同,如在IBM XL C++是__restrict__),而這個是真的可以幫助編譯器做優化的東西,因為它可以限制住Pointer Alias,而Pointer Alias是影響編譯器優化的一個很重要的因素。

再補充一個Herb Sutter的文章吧:GotW #81: Constant Optimization?


沒用的。const是為了讓類的作者提供更好的演算法(當然這意味著你隨便const_cast可能導致傻逼而且沒人保護你),而不是讓編譯器優化出更好的結果的。


沒有。編譯出來的機器碼應該是一樣的。const大概主要是為了編譯時候幫你檢查出一些潛在的讀寫錯誤。加了const的成員函數不應該修改對象內其它成員的值。

————————————原答案————————————

見到其它幾樓不同見解的答案,感覺答的有點草率,我稍微做了點研究。

1. @楚軒提到的優化問題。我也意識到這是個好思路,不過有人認為目前編譯器似乎不會這麼做。因為const屬性可以被const_cast去除,對於編譯器來說這個優化的機會並不好。

參考:Const Correctness, c++ - Can const-correctness improve performance?

2. @于洋提到的COW問題。我搜到的結果並不是現階段C++語言本身支持COW,而是我們自己的代碼實現了這一特性。因此說const是實現這一特性基礎沒問題,但我並不同意const會對成員函數的性能有提升。

參考:More C++ Idioms/Copy-on-write


和性能毫無關係。這是語言層面的一種約束。換句話說,提供了「語義」限制,並提供給編譯器更多信息,令它能夠對程序員的行為進行更進一步的約束。提高了程序開發的準確性。


有,否則C++怎麼實現Copy On Write?


,很多,舉例:

#include &

class Counter {
public:
int getSize(int* p) /*const*/ { --p; return m_size; }
private:
int m_size=10;
};

int main()
{
int* evilPtr;
Counter x;
std::cout &<&< "please enter a ptr:"; std::cin &>&>(uintptr_t)evilPtr;
for(int i = 0; i &< x.getSize(evilPtr); ++i); return 250; }

因為在以上代碼里編譯器在編譯期絕沒有任何可能能夠知道evilPtr指向哪裡,所以它只能假定evilPtr可能正在指向x.m_size,由於不知道m_size可能被意外改變,那麼,for循環中的" i &< x.getSize() "中的

x.getSize()必須每次循環都調用一次,即使inline掉函數本身,也必須每次都從內存讀一次m_size.

那麼,如果將getSize()改成const: 那麼,編譯器就能夠知道,在循環中的每一次調用getSize,m_size都不可能被修改,於是就敢隨便優化循環了.

可能有人會問,即使getSize()改成const,evilPtr還是有可能指向m_size啊,對,但那是UB.

還有const_cast,const_cast不是用來去掉const變數的const的.那也是UB.


有助於。因為編譯器知道了更多關於類數據成員不會再此函數內被修改的信息,可以做出更大膽的優化


看了各位答案,更加糊塗了。


我發現這裡回答的有很多大牛,但是大家都覺得編譯器優化的時候會去考慮const_cast或者多線程,所以const是沒用的,但是實際上不是這樣的,你可以嘗試下這樣的代碼:

#include &

int main() {
const int x = 10;
*const_cast&(x) = 11;
printf("%d
", x);
return 0;
}

我在gcc4.8下測試甚至是O0的情況下輸出都是10

如果你想要編譯器確實的去訪問這個內存而不進行優化,應該人為加上volatile關鍵字,反正這點上千萬別相信編譯器!!

當然我不認為對member function加const一定有多大作用,但是以const_cast或者並發作為理由說編譯器不會優化是不成立的......


推薦閱讀:

C++LNK2019錯誤如何解決?
對於 C++ 的疑惑?
vs2010 程序退出的時候崩潰地方,不知道如何解決?
C++多線程環境下里如何精確獲取shared_ptr的引用計數?
如何評價Andrei Alexandrescu提出的c++ policy-based design?

TAG:編程語言 | C | 程序優化 |