2014-11-26 28 views
5

codice minimo che riproduce il problema:Perché il compilatore utilizza una variabile temporanea?

#include "stdafx.h" 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CComBSTR ccbTest(L"foo"); 
    const wchar_t * pTest = ccbTest ? ccbTest : L"null string"; 

    return 0; 
} 

Il compilatore utilizza una temporanea CComBSTR quando vuole memorizzare un puntatore in pTest. Quindi utilizza la conversione BSTR disponibile nella classe CCcomBSTR, con il temporaneo e memorizza il puntatore in pTest. Quindi il temporaneo viene distrutto e mi viene lasciato un puntatore pendente in pTest.

La correzione è quello di lanciare la CComBSTR:

const wchar_t * pTest = ccbTest ? static_cast<BSTR>(ccbTest) : L"null string"; 

Non capisco il motivo per cui la correzione è necessaria. Ho pensato che il compilatore avrebbe solo provato a convertire in BSTR tutto da solo. Perché un temporaneo?

risposta

2

Il temporaneo esiste per gli stessi motivi this question.

E, come detto in one of its answer:

Il tipo del ternario:? Espressione è il tipo comune del suo secondo argomento e terzo. Se entrambi i tipi sono uguali, si ottiene un riferimento indietro. Se sono convertibili l'uno con l'altro, uno viene scelto e l'altro viene convertito [...]. Poiché non è possibile restituire un riferimento lvalue a una variabile temporanea (la variabile convertita/promossa ), il suo tipo è un tipo di valore.

Poiché il L"null string" è un temporaneo di tipo diverso rispetto CComBSTR tutta risultato del ternario è un tipo di valore che indica il risultato viene copiato in un temporaneo.

se provate:

CComBSTR ccbTest(L"foo"); 
CComBSTR ccbNull(L"ull string"); 

const wchar_t * pTest = ccbTest ? ccbTest : ccbNull; 

Non c'è più temporanea.

0

Non vedo un CComBSTR temporaneo nell'esempio precedente.

CComBSTR è una classe di wrapper RAII utilizzata per aiutare a gestire la durata di BSTR e quando sarà fuori dal campo di applicazione, il BSTR sottostante verrà distrutto.

ccbTest è una variabile automatica (stack) e quando esce dal campo di applicazione (alla fine di _tmain) e il BSTR che gestisce verranno distrutti.

+0

Si prega di provare il mio codice, eseguire il debug e inserire le chiamate: c'è un temporaneo, anche se non "lo vedi" :-) – manuell