4

たとえば、短絡されたブール式があると想像してください。

f(g() && std::string().size() == 0);

std::string仮設の寿命を考えています。通常、コンパイラは full-expression の最後で一時変数を破棄します。g()ただし、この場合、 true が返されたかどうかがわからないため、適切ではありません。そのため、コンパイラが通常この状況をどのように処理するかを知りたいと思いました。デストラクタ呼び出しを発行するかどうかを示す変数を格納していますか? それとも、標準では、一時的な早期の破壊を許可していますか?

4

1 に答える 1

2

&&true が返されたstd::string().size()場合にのみ評価されます。g()IOWg()が true を返さなかった場合、一時的な文字列を破棄するタイミングに問題はありません。そもそも一時的な文字列が作成されることはないためです。

たとえば、次のようなコードがあるとします。

#include <iostream>
#include <stdlib.h>

bool g() { return rand() & 1 == 0; }

void f(bool val) {
    std::cout << std::boolalpha << val;
}

int main(){
    f(g() && std::string().size() == 0);
}

VC++ は、一時変数が生成されたかどうかを追跡する一時変数を使用するコードを$T1生成し、真の場合にのみ一時変数を破棄する$T1ため、シーケンスは次のようになります。

    int $T1 = 0
    call g()
    if (retval == 0)
        goto $LN3

    call std::string::string()
    $T1 = true;
    call temp_string.size();
    if (retval != 0)
        goto $LN3

    $TV74 = 1
    goto $LN4    

$LN3 :
    $TV74 = 0
$LN4 :
     call f($TV74);

    if ($T1 == 0)
        goto $LN7

    call std::string::~string();

$LN7:
    return 0;

アセンブリ言語からこの疑似コードに翻訳し直す​​際に、無関係な詳細をいくつか省略しましたが、必要に応じて元のフローと比較するのが非常に簡単になるように、元のフローと十分に類似した名前を保持しています。

于 2013-11-14T16:43:11.613 に答える