2017-11-27 7 views
0

g++clang++を使用する場合、++my string==my string##my string--が得られます。 MSVCとインテルコンパイラの間は++==my string##my string--です。C++ string.c_str()

なぜですか?

#include <string> 
#include <iostream> 

using namespace std; 

string test() 
{ 
    string s0 = "my string"; 
    return s0; 
} 

int main() 
{ 
    string s = test(); 
    const char* s1 = test().c_str(); 
    const char* s2 = s.c_str(); 
    cout << "++" << s1 << "==" << s2 << "##" << test().c_str() << "--" << endl; 
    return 0; 
} 

これは未定義の動作ですか?コメントで

+16

's1'はもはや存在しないオブジェクトを指します。それを読むには、明確に定義されていない動作です。 –

+0

未定義の動作を "コードからアセンブラへの未定義の変換"と混同しないでください。観察可能な振る舞い(言葉によって定義されるように)が同じであれば、コンパイラはどのような方法でもコードを変換することができます。これは[そのままの場合のルール](http://en.cppreference.com/w/cpp/language/as_if)として知られています。 –

+1

一時的なオブジェクトの混乱を返す[C++の重複]の可能性があります(https://stackoverflow.com/questions/12952295/c-returning-temporary-objects-confusion) – wally

答えて

6

は、あなたが尋ねた:

test().c_str()は動作しますが、s1できないのはなぜ?

test().c_str()は、すべてのコンテキストではなく一部のコンテキストでのみ機能します。

std::cout << test().c_str() << std::endl; 

は、文の実行が完了するまで生き続けるために必要とされるtest()によって返された一時的なので、動作が保証されています。一方

、一時は最初の行の実行完了を超えて生きるために必要とされていないため、

char const* s1 = test().c_str(); 
std:cout << s1 << std::endl; 

は未定義の動作です。

関連する問題