2012-07-15 36 views
13

澄清:鑑於文字的字符串可以被(見下文)重寫爲const char[],強加文字較低的最高長度比 char[] s是隻是一個句法不便。爲什麼C標準 鼓勵這個?爲什麼C字符串的最大長度與max char []不同?


的C89標準對字符串字面翻譯的限制:在一個字符串

509個字符的文字或寬字符串文字(後串聯)

沒有一個字符數組的限制;也許

32767字節的對象(僅在託管環境)

適用(我不知道是什麼意思的對象或託管環境中),但無論如何這是一個更高的極限。

我的理解是,一個字符串文字相當於包含字符的字符數組,即:它總是能夠改寫這樣的事情:

const char* str = "foo"; 

這個

static const char __THE_LITERAL[] = { 'f', 'o', 'o', '\0' }; 
const char* str = __THE_LITERAL; 

那麼,爲什麼這樣的硬性文字限制?

+6

很奇怪他們選擇了509而不是65533或253. – 2012-07-15 01:14:37

+3

您可能希望閱讀這篇文章:http://msdn.microsoft.com/en-us/library/sx08afx2.aspx – 2012-07-15 01:19:22

+2

程序限制*源*與編譯程序的限制無關。 – 2012-07-15 01:25:41

回答

14

字符串文字的限制是編譯時的要求;邏輯源代碼行的長度也有類似的限制。編譯器可能使用固定大小的數據結構來保存源代碼行和字符串文字。

(C99將這些特定限制從509個字符增加到4095個字符。)

另一方面,可以在運行時建立一個對象(例如數組char)。限制可能由目標機器架構強加,而不是由編譯器的設計決定。

請注意,這些是而不是強加給程序的上限。編譯器不需要強加任何有限的限制。如果編譯器確實對行長施加了限制,則它必須至少爲509或4095個字符。 (我認爲大多數實際的編譯器並沒有強加固定的限制,而是動態地分配內存。)

+0

雖然當然有一個實際的限制 - 如果編譯器是一個32位可執行文件,它當然不能處理4G以上的字符串文本(儘管有目標文件格式限制)。實際的限制當然會低得多。 – 2012-07-15 01:58:03

+0

編譯時是不是初始化的'const char []'? – npostavs 2012-07-15 14:13:30

+0

@npostavs:它可以,但32767字節的限制(在C99中增加到65536)適用於運行時對象,無論它們是如何構建的。 – 2012-07-15 17:22:15

4

並不是說509個字符是字符串的限制,它是ANSI兼容性所需的最小值,如解釋here所解釋的。

我認爲這個標準的製造商從他們的屁股中抽出了509個,但除非我們從中得到一些官方文檔,否則我們無法知道。

只要多少個字符實際上可以在字符串文字中,即依賴於編譯器。

下面是一些例子:

  • MSVC:2048
  • GCC:無限制(可達10萬字),但給後510個字符的警告:

    字符串文字的長度100000超過C90編譯器需要支持的最大長度509

+0

有趣的信息,但它並沒有真正回答這個問題。 – 2012-07-15 01:27:35

+0

@KeithThompson我不同意。它回答了這個問題,它解釋說它不是'限制',而是'最低限度',所以在大多數編譯器中,不會有任何區別。 – 2012-07-15 01:29:00

+0

我認爲關鍵是標準中引用的509是最小值,而不是最大值。 – 2012-07-15 01:29:39

0

對不起,關於最近的答案,但我想說明兩種情況之間的區別(Richard J. Ross已經指出,他們是不相等)

假設你試試這個:

const char __THE_LITERAL[] = { 'f', 'o', 'o', '\0' }; 
const char* str = __THE_LITERAL; 
char *str_writable = (char *) str; // Not so const anymore 
str_writable[0] = 'g'; 

現在str包含 「咕」。

但是,如果你這樣做:

const char* str = "foo"; 
char *str_writable = (char *) str; 
str_writable[0] = 'g'; 

結果:段錯誤! (至少在我的平臺上)。

以下是最基本的區別:在第一種情況下,您的數組已初始化爲「foo」,但在第二種情況下,您具有實際的字符串文字。

在一個側面說明,

const char __THE_LITERAL[] = { 'f', 'o', 'o', '\0' }; 

是完全等同於

const char __THE_LITERAL[] = "foo"; 

這裏=充當數組初始化而不是分配。這與

有很大不同
const char *str = "foo"; 

其中字符串文字的地址被分配到str

+0

哦,我的意思是__THE_LITERAL是一個靜態變量,在這種情況下,segfault會導致這兩種情況。 – npostavs 2013-01-18 15:12:44

+0

@npostavs:嗯,你說得對。有趣。其實我錯誤地認爲'=「foo」'正好被視爲'= {'f','o','o','\ 0'}'。如果我用超過509個字符做同樣的事情,gcc會在第一種情況下給出警告,但不會在第二種情況下給出警告。我猜這是因爲Keith Thompson上面所說的 - 編譯器可能使用固定大小的數據結構來處理文字。 – 2013-01-19 00:36:48