Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the compiler use a temporary variable?

Minimal code reproducing the problem:

#include "stdafx.h"


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

    return 0;
}

The compiler uses a temporary CComBSTR when it wants to store a pointer in pTest. It then uses the BSTR conversion available in the CCcomBSTR class, with the temporary, and stores the pointer in pTest. Then the temporary is destroyed, and I am left with a dangling pointer in pTest.

The fix is to cast the CComBSTR:

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

I don't understand why the fix is necessary. I thought that the compiler would just try to convert to BSTR all by itself. Why a temporary?

like image 285
manuell Avatar asked Nov 01 '22 13:11

manuell


1 Answers

The temporary exist for the same reasons this question does.

And as stated in one of its answer:

The type of the ternary ?: expression is the common type of its second and third argument. If both types are the same, you get a reference back. If they are convertable to each other, one gets chosen and the other gets converted [...]. Since you can't return an lvalue reference to a temporary (the converted / promoted variable), its type is a value type.

Since your L"null string" is a temporary of a different type than CComBSTR the whole result of the ternary is a value type which means the result is copied in a temporary.

If you try:

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

const wchar_t * pTest = ccbTest ? ccbTest : ccbNull;

There is no more temporary.

like image 178
Drax Avatar answered Nov 15 '22 05:11

Drax