2016-09-27 11 views
5

私はcheckg gccとclangを持っており、両方とも警告を生成しません。私は、foo()からの一時的な生涯は、bar関数呼び出しのセミコロンが置かれている完全な式の終わりまで延長されると考えます。このコードはUBを引き起こしますか?

#include <iostream> 
#include <string> 

struct A 
{ 
    std::string foo() const{ return "aaa"; } 
}; 

void bar(const char* c) { 
    std::cout << c; 
} 

int main() 
{ 
    A a; 
    bar(a.foo().c_str()); // Is this safe? 
    bar(a.foo().substr().c_str()); // or this 
} 
+0

はい、あなたは正しい、それは –

答えて

7

foo()(およびsubstr())によって返され、一時は、これは安全である、(メソッド呼び出しのチェーンの後)barコールの終わりまで存在し続けます。

int main() 
{ 
    A a; 
    bar(a.foo().c_str()); 
    //temporary is destroyed here 
    bar(a.foo().substr().c_str()); 
    // and here 
} 

クラシック未定義の動作の場合:一時std::stringが作成され

int main() 
{ 
    A a; 
    const char* charPtr = a.foo().c_str(); 
    printf("%s", charPtr); 
} 

、それへのポインタが、バッファはc_str()によって返され、一時的には、スコープの外に出ると、破壊されています。 charPtrは無効な場所(デッドstd::string)を指すポインタです。

+0

UBの例では、正確に右ではありません安全です。 charPtrは、aで非const演算が呼び出されるまで有効です。 – Trevir

+0

@Trevir 'printf'を使ってそれを印刷しようとすれば十分です。 –

+0

printfはオブジェクトaとどのように干渉しますか? – Trevir

2
bar(a.foo().c_str()); 
bar(a.foo().substr().c_str()); 

短い回答 - 両方とも安全です。

あなたが見ているのは、の値がです。

右辺値(いわゆる、歴史的に、代入式の右側に表示される可能性が右辺値であるため)はxValue、その一時的なオブジェクトまたはサブオブジェクト、または関連付けられていない値でありますオブジェクト。

続きを読む:What are rvalues, lvalues, xvalues, glvalues, and prvalues?

+1

これは正価であることは本当にポイント –

+0

ではありませんか? c_str()は、rvalueオブジェクトへのポインタを返します。それはちょっと問題です。このポインタを保存すると危険です! –

関連する問題