2013-08-24 104 views
5

出於好奇,我想知道C++字符串文字的真正底層類型是什麼。C++字符串文字的類型

根據我觀察到的情況,我得到了不同的結果。

一個typeid的測試類似如下:

std::cout << typeid("test").name() << std::endl; 

顯示我char const[5]

嘗試指派一個字串不兼容的類型,像這樣(見給定的錯誤):

wchar_t* s = "hello"; 

我得到a value of type "const char *" cannot be used to initialize an entity of type "wchar_t *"從VS12的智能感知。

,但我看不出它如何能const char *爲以下行由VS12接受:

char* s = "Hello"; 

我已閱讀,這是在預C++ 11個標準允許的,因爲它是與C兼容,但修改s會導致未定義的行爲。我認爲這只是VS12還沒有實現所有的C++ 11標準,並且這條線通常會導致錯誤。

讀C99標準(from here,6.4.5.5)表明它應該是一個數組:

的多字節字符 序列然後用於初始化靜態存儲持續時間和長度的數組只是 足以包含序列。

那麼,什麼是C++字符串文字下的類型?

非常感謝您寶貴的時間。

+5

VS12講的是一些與C++類似但不相同的奇怪方言。 –

回答

8

字符串文字的類型確實是const char[SIZE],其中SIZE是字符串加上空終止字符的長度。

事實上,你有時看到const char*是因爲通常的陣列到指針的衰減。

,但我看不出它如何能const char *爲以下行由VS12接受: char* s = "Hello";

這是在C++ 03(正確的行爲作爲例外平時常量正確性規則),但自此以來它已被棄用。符合C++ 11的編譯器不應該接受該代碼。

+2

「通常的數組到指針衰減」不會在所有上下文中出現。在C中,除非數組表達式是一元'&'或'sizeof'的操作數,或者是用於初始化數組(子)對象的初始化程序中的字符串文字,否則會發生。 C++有更多的例外。 –

+0

正確的術語是_Array-to-pointer Conversion_,它是最新C++標準第4節中記錄的_Standard Conversion_。粗略地說,標準轉換可能會在某些情況下被編譯器隱式應用於表達式。 –

5

字符串文字的類型是char const[N]其中N是包含終止空字符的字符數。雖然這種類型的確不是而不是轉換爲char*,但C++標準包含一個允許將字符串文字分配到char*的子句。添加了此條款以支持兼容性,特別是對於當時沒有const的C代碼。

在標準的類型相關的條款是2.14.5 [lex.string]段8:

普通字符串和UTF-8字符串文字也稱爲窄字符串文字。窄字符串文字的類型爲「n常量字符數組」,其中n是下面定義的字符串的大小,並且具有靜態存儲持續時間(3.7)。

+1

請注意,此異常條款現在已被棄用,並試圖將字符串文字分配給'char *'應該會產生編譯時錯誤。 – syam

+0

@syam - 「已棄用」意味着它仍然合法,但可能在將來消失。在C++ 03中不推薦將字符串文字轉換爲'char *';它在C++ 11中變得無效。但是,語言定義不需要「編譯時錯誤」。對於違反可診斷約束條件的情況,唯一的要求是編譯器發出診斷信息;這樣做後,可以繼續編譯代碼。這是實現特定擴展的鉤子。只有一種情況需要編譯器拒絕編譯代碼:'#error'指令。 –

-1

首先,一個C++字符串文字的類型是Ñconst char陣列。其次,如果要用字符串文字初始化wchar_t,則必須編碼:

wchar_t* s = L"hello" 
+0

這並不意味着要成爲有效的代碼,只有測試才能看到給定的錯誤。不過,這個標準確實使它聽起來應該是一個數組。 –

+7

不,如其他答案中所解釋的,字符串文字不是「const char *」,而是「const char [SIZE]」。 -1 – syam

+1

然後解釋爲什麼'sizeof「hello,world」'得到13. –