2016-05-15 6 views
6

次のコードはなぜコンパイルされますか?それはコンパイルされ、clangでうまく動作し、first.を印刷します。しかし、正しい動作は、不平を言って、適切なエラーを出すべきだと思います。C++ std :: string初期化の動作が正しくありません

#include <iostream> 
#include <string> 

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

この質問は、thisにインスパイアされています。

+0

これは、「最初の」文字列の最後に暗黙の「\ 0」があるためです。これは 'string'オブジェクトに、より多くの文字を探すのを止めるように指示します"second"のメモリに) – DarthRubik

+1

@DarthRubik:いいえ、それは何が起こっているのではありません。 –

+0

根本的な問題は[この問題](https://stackoverflow.com/questions/24112281/c11-initializer-list-fails-but-only-on-lists-of-length-2)と同じです。 – chris

答えて

9

std::stringには、2つのイテレータを使用するテンプレートコンストラクタがあります。文字列リテラルを渡すと、イテレータとして機能するchar const*に崩壊します。ただし、これらのポインタは有効な範囲を構成しないため、未定義の動作が発生します。

+0

これはclangのバグです。あれは正しいですか? @EissaN。 –

+0

いいえ、あなたのコードのバグです。あなたのプログラムは未定義の動作を示します。したがって、clangは特に何かをする義務はなく、C++標準に関する限り、何もしないでください。 –

4

これは未定義の動作です。

これは、イテレータの開始と終了の2つのイテレータを受け入れるコンストラクタstd::stringを呼び出しています。どちらの初期化パラメータも同じ型を持つため、イテレータのペアとして解釈され、この特定のオーバーロードされたコンストラクタに一致します。

文字ポインタの値は、イテレータの開始/終了の値として解釈されます。 clangでうまくいくのですが、gccでは例外がスローされます。

関連する問題