2009-12-08 74 views
1

如果我調用一個函數,如 myObj.setType(「fluid」); 多次在一個程序中,多少個文字「流體」的副本被保存在內存中?編譯器是否可以識別出這個文字已經被定義並且只是再次引用它?(c/C++)在文本部分做字符串文本共享內存的副本?

+1

如果你多次使用「流體」,也許你應該定義一個常量並引用常量而不是文字? – FrustratedWithFormsDesigner 2009-12-08 22:31:21

+1

如何編寫一個小測試,通過比較不同文字指向的位置來檢查這一點? – 2009-12-08 22:33:02

+1

呵呵,關於這個標題,很多鏈接器都會識別一個'.rodata',其中(例如)文字串屬於。理論上'.text'應該保留給代碼,儘管濫用是普遍的 - 也許是出於歷史原因。 – 2009-12-08 22:41:08

回答

0

我相信,在C/C++沒有該情況下,沒有指定的處理,但在大多數情況下會使用該字符串的多個定義。

+0

該標準不要求或排除interned字符串。 Meyers談論了Interceptor對象在_Effective C++ _中的問題(它實際上可能在_More Effective C++ _中)。 – KitsuneYMG 2009-12-09 04:39:34

15

這與C++(語言)無關。相反,它是編譯器可以執行的「優化」。所以,答案,這取決於您使用的編譯器/平臺。

@大衛這是從latest draft of the language

§2.14.6(第28頁)

是否所有字符串文字是 不同(即,存儲在非 重疊對象)是 實現定義。試圖修改字符串文字 的 的效果是undefined

重點是我的。

換句話說,C++中的字符串文字是不可變的,因爲修改字符串文字是未定義的行爲。所以,編譯器是免費的,以消除多餘的副本。

BTW,我只談論C++)

+0

如今,字符串文字「重疊」是否是_unspecified_。 – 2017-05-25 19:00:33

4

是的,可以,但不能保證它會的。定義一個常數,如果你想確定。

+4

+1我會補充說「定義一個常量」意味着'const char cst [] =「foo」;'。 「定義」這個詞可能會引起錯誤的想法。 – 2009-12-08 22:37:01

0

2.13.4/2:「是否所有字符串文字都是不同的(即存儲在非重疊對象中)是實現定義的」。

這允許您所問的優化。

順便說一句,可能存在一些含糊不清的情況,至少在標準的這一部分內是局部的。字符串常量的定義並不十分明確地告訴我下面的代碼是否使用一個字符串字面量的兩倍,或兩個字符串字面量各一次:

const char *a = ""; 
const char *b = ""; 

但接下來的一段說:「在翻譯階段6個相鄰窄字符串文字連接「。除非意思是說某些東西可以與自身相鄰,否則我認爲其意圖非常清楚,該代碼使用了兩個字符串文字,它們在階段6中連接在一起。因此,這不是一個字符串字面量的兩倍:

const char *c = "a" "a"; 

不過,如果你讀過「一」和「一個」是相同字符串字面量,那麼標準要求你在談論的最優化。但我不認爲它們是相同的字面意思,我認爲它們是不同的文字,恰好由相同的字符組成。這在標準的其他地方可能已經明確,例如在關於語法和解析的一般信息中。

無論是明確與否,許多編譯器作家解釋的標準,我認爲它是這樣的,所以我也可能是正確的;-)

1

這是一個編譯器的實現問題。我用過的許多編譯器都可以選擇共享或合併重複的字符串文字。允許重複的字符串文字加快編譯過程,但會產生更大的可執行文件。