2011-08-04 15 views
2

非常經常將指針作爲函數參數傳遞給只讀參數(例如結構體等)。例如,在這個構造函數中:爲什麼很少有人輸入常量正確的代碼?將const更正/更快的代碼編譯?

Chunk::Chunk(const string& text, COLOR * background, COLOR * foreground); 

我用這種方式(不是const-correct),因爲我認爲它更容易閱讀。 不過,我開始覺得這是骯髒的,做相反:

Chunk::Chunk(const string& text, const COLOR * const background, 
          const COLOR * const foreground); 

這似乎很難理解在第一,但只有等到你使用它。我的問題:

爲什麼沒有人這樣做是正確的? (我見過這樣的小代碼) 編譯好了/更小/更快?

知道有什麼區別,但我真的不在意不同的語義,因爲任何人閱讀代碼可以看到參數是隻讀的。 (誰會改變一個指針地址?)

知道我可以使用引用來代替,但我們假設我不想(或我在純C)。

+1

也許除非你需要一份 –

+8

我不同意你應該寫'常量字符串和text'。與我們合作的大多數人對我們的代碼的成本正確性非常嚴格。 –

+1

我不認爲,這真的是一個技術問題,爲什麼有人寫一個錯誤的代碼 –

回答

0

const正確性有助於編譯器生成更快的代碼。例如,如果將一個非const指針傳遞給一個函數,編譯器可能會認爲該函數修改了引用的內存塊。

編輯:(從特殊C++風格40個新的工程難題,編程問題和解決方案)

是否聲明爲const幫助編譯器生成更優化的代碼或以其他方式改善其參數和/或返回值代碼生成?

總之,不,它可能沒有。

爲什麼或爲什麼不?

編譯器能做些什麼更好?它可以避免參數或返回值的副本嗎?不,因爲參數已經通過引用傳遞,並且返回已經通過引用。可以將x或someY的副本放入只讀存儲器嗎?不,因爲x和someY都超出了它的範圍,並且來自和/或被賦予了外部世界。即使有些是在f本身內部動態分配的,它和它的所有權也被放棄給調用者。

但是,如何優化代碼出現在f主體內?由於常量,編譯器是否可以改進它爲f主體生成的代碼?

只是因爲x和someY被聲明爲const並不一定意味着它們的位在物理上是const的。爲什麼不?因爲任何一個類都可能具有可變成員或他們的道德等價物,即成員函數內的const_casts。事實上,f本身內部的代碼可能會執行const_casts或C型轉換,將常量聲明轉化爲謊言。

有一種情況說const可以真正意味着什麼,也就是說當對象被定義爲const時。在這種情況下,編譯器通常可以成功地將這些「真正的const」對象放入只讀存儲器中,尤其是如果它們是可以在編譯時創建內存映像並因此可以存儲在程序可執行映像本身內部的POD。這些物體通俗地稱爲「ROM-able」。

常見的正確性有助於編譯器生成更緊密的代碼。是的,const的確是一件好事,但這個條款的重點在於const主要是針對人類,而不是編譯器和優化器。

+8

不是真的。 Const正確的代碼使維護代碼更容易,因爲它記錄了意圖。 –

+0

使用'const'確實沒有太多的性能好處。另見[C++中的常量和編譯器優化](http://stackoverflow.com/questions/212237/constants-and-compiler-optimization-in-c)來自維基百科的 –

+0

:三個優點:...編譯器可能知道對象的值一旦創建就不會改變,從而執行代碼優化。 – cprogrammer

0

我相信const的主要特點是編譯時正確性檢查,性能增加更像是一個愉快的副作用。

+1

除了沒有這樣的效果。優化甚至沒有「看」的引用或指針的常量性,它只是東西,沒有任何語義都在這一水平。 const正確性已被設計成對於程序員來說,沒有編譯器的幫助......這是國際海事組織也值得懷疑,如果它是程序員的幫助,但這是另一個故事。 – 6502

3

在這個例子中,你所列出

Chunk::Chunk(string text, const COLOR * const background, 
          const COLOR * const foreground); 

你或許應該還const&傳遞字符串,除非您有意該字符串的本地副本。另外,在我看來,顏色參數應該被聲明爲const COLOR *而不是const COLOR * const。第二個const只是表示該函數不會將background和​​指針重新指向本地其他一些內存塊。它不會影響調用者,因此它是一個實現細節。因此,即使執行文件中明確列出了他們爲const COLOR * const原型在頭應改爲

Chunk::Chunk(string text, const COLOR *background, 
          const COLOR *foreground); 
+1

1,另外,在第二個'const':標準狀態,在一個*函數聲明*,參數類型的常量性從簽名(其中參數類型在這種情況下是'COLOR常量被刪除* ')。它在*函數定義*中不同,它告訴編譯器它應該在內部檢查賦值。 –

相關問題