2016-05-15 53 views
6

爲什麼下面的代碼會被編譯?它編譯和運行良好與鐺和打印first.但是,我相信正確的行爲應該抱怨併發出適當的錯誤。C++ std :: string初始化的錯誤行爲

#include <iostream> 
#include <string> 

int main() 
{ 
    std::string s{ "first", "second" }; 
    std::cout << s << std::endl; 
} 

這個問題的靈感來自this

+0

這是因爲「第一個」字符串在其末尾有一個隱含的「\ 0」....它告訴字符串對象停止查找更多字符(即使它仍然可以分配滿記憶中的「第二」) – DarthRubik

+1

@DarthRubik:不,那不是發生了什麼。 –

+0

底層問題與[此問題]相同(https://stackoverflow.com/questions/24112281/c11-initializer-list-fails-but-only-on-lists-of-length-2)。 – chris

回答

9

std::string有一個需要兩個迭代器的模板構造函數。當你傳遞字符串文字時,它們會衰減到char const*,這就是一個迭代器。但是,由於這些指針不構成有效範圍,因此您有未定義的行爲。

+0

然後,這是一個叮噹中的錯誤;那是對的嗎? –

+0

@EissaN。不是。這是你的代碼中的一個錯誤。你的程序展現出未定義的行爲,因此鏗鏘聲明沒有義務做任何事情,並且就C++標準而言,可以做任何事情。 –

4

這是未定義的行爲。

這是調用std::string的構造函數,它接受兩個迭代器,開始和結束迭代器值。因爲兩個初始化參數都有相同的類型,所以它們被解釋爲一對迭代器,並匹配這個特定的重載構造函數。

字符指針的值被解釋爲開始/結束迭代器值。它恰好與clang一起工作,但是使用gcc會引發異常。