2 回答

TA貢獻1860條經(jīng)驗 獲得超8個贊
您不能依賴具有相同存儲位置的相同字符串文字,這是一個實現(xiàn)決策。在C99標準草案告訴我們,這是不確定的相同的字符串字面是否是不同的,從部分6.4.5 字符串文字:
如果它們的元素具有適當?shù)闹?,則不確定這些數(shù)組是否不同。如果程序嘗試修改這樣的數(shù)組,則行為是不確定的。
對于C ++,這在草案標準部分的2.14.5 字符串文字中進行了說明,該文字說:
是否定義了所有字符串文字(即存儲在不重疊的對象中)都是實現(xiàn)定義的。嘗試修改字符串文字的效果是不確定的。
編譯器允許池字符串常量,但你必須了解它的編譯器是如何工作的編譯器,因此這不會是便攜,可能會改變。Visual Studio包含用于字符串文字池的選項
在某些情況下,可以合并相同的字符串文字以節(jié)省可執(zhí)行文件中的空間。在字符串文字池中,編譯器使對特定字符串文字的所有引用都指向內(nèi)存中的同一位置,而不是使每個引用都指向字符串文字的單獨實例。要啟用字符串池,請使用/ GF編譯器選項。
請注意,在某些情況下,它確實符合條件。
gcc確實支持池化和跨編譯單元,您可以通過-fmerge-constants啟用它:
嘗試在編譯單元之間合并相同的常量(字符串常量和浮點常量)。
如果匯編器和鏈接器支持,則此選項是優(yōu)化編譯的默認選項。使用-fno-merge-constants禁止此行為。
注意,嘗試的使用以及如果...支持它。
至于至少下不需要的理由字符串常量被合并,我們由此可以看出在字符串文字存檔comp.std.c討論的理由是由于各種各樣的時候實現(xiàn)的:
GCC可能只是一個例子,但不是動機。在ROMmable數(shù)據(jù)中使用字符串文字的部分原因是為了支持ROMming。我隱約記得使用了C的兩個實現(xiàn)(在做出X3J11決定之前),在這些實現(xiàn)中字符串文字被自動合并或存儲在常量數(shù)據(jù)程序部分中??紤]到現(xiàn)有的各種實踐以及當需要原始UNIX屬性時可以使用的簡便解決方法,似乎最好不要嘗試保證字符串文字的唯一性和可寫性。

TA貢獻1780條經(jīng)驗 獲得超1個贊
不,您不能期望使用相同的地址。如果發(fā)生這種情況,就會發(fā)生。但是并沒有強制執(zhí)行。
§2.14.5 / p12
是否定義了所有字符串文字(即存儲在不重疊的對象中)都是實現(xiàn)定義的。嘗試修改字符串文字的效果是不確定的。
編譯器可以隨心所欲。如果它們位于不同的翻譯單元中,或者即使它們位于同一翻譯單元中,則它們可以存儲在不同的地址中,而不管它們是只讀存儲器。
在MSVC,例如,地址是在這兩種情況完全不同,但同樣:沒有什么能阻止編譯器合并指針的值(甚至沒有在那里,只要只讀段約束義務)。
- 2 回答
- 0 關注
- 510 瀏覽
添加回答
舉報