2013-11-14 2 views
4

Представьте себе, что у нас есть короткое замыкание логического выражения, например,короткозамкнутой временный срок службы

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

Я думаю о время жизни std::string временных. Обычно компилятор уничтожает временные ряды в конце полного выражения. Но в этом случае это не подходит, потому что не знает, вернётся ли g(). Поэтому я хотел знать, как компиляторы обычно справляются с этой ситуацией. Сохраняют ли они переменную, сообщающую им, нужно ли вызывать вызов деструктора? Или Стандарт разрешает им рано или поздно разрушать временное?

+2

Я уверен, что стандарт даже не позволяет создавать временные объекты, если 'g()' не возвращает true. ('&&' формирует точку последовательности.) – cHao

+0

Да, это * проблема *, к которой я отношусь. – Puppy

ответ

2

&& короткое замыкание, поэтому std::string().size() будет оцениваться (вообще), если g() верен. IOW, если g() не вернул 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; 

Я оставил из некоторых несоответствующих деталей в переводе обратно с языка ассемблером в этом псевдокод, но г etained оригинальный поток и достаточно похожие имена, что довольно легко сравнить их с оригиналом, если хотите.

+0

Да, но поскольку вы не знаете, возвращает ли 'g()' true, у вас есть проблема, потому что, когда 'f' вернулась и пришло время для очистки, вы не знаете, статически ли это или нет временное создание. – Puppy

+0

Если я пишу компилятор, я бы сгенерировал код, несколько эквивалентный 'auto temp = g(); if (temp) {temp = (std :: string(). size() == 0); } f (temp); '. – cHao

+0

@cHao: Это приводит к разрушению временного раннего. – Puppy

Смежные вопросы