【问题标题】:Why does the compiler use a temporary variable?为什么编译器使用临时变量?
【发布时间】:2015-01-25 00:53:01
【问题描述】:

重现问题的最少代码:

#include "stdafx.h"


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

    return 0;
}

当编译器想要在pTest 中存储一个指针时,它会使用一个临时的CComBSTR。然后它使用CCcomBSTR 类中可用的BSTR 转换和临时值,并将指针存储在pTest 中。然后临时对象被销毁,我在pTest 中留下了一个悬空指针。

解决方法是投射CComBSTR:

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

我不明白为什么需要修复。我认为编译器只会尝试自行转换为BSTR。为什么是临时的?

【问题讨论】:

    标签: c++ visual-studio-2010 atl ternary-operator bstr


    【解决方案1】:

    临时存在的原因与this question 相同。

    one of its answer中所述:

    三元?的类型:表达式是其第二个的常用类型 和第三个论点。如果两种类型相同,您将获得参考 背部。如果它们可以相互转换,则选择一个,然后 其他被转换[...]。既然回不去了 对临时对象的左值引用(转换/提升 变量),它的类型是值类型。

    由于您的 L"null string" 是与 CComBSTR 不同类型的临时值,因此三元的整个结果是值类型,这意味着结果被复制到临时值中。

    如果你尝试:

    CComBSTR ccbTest( L"foo" );
    CComBSTR ccbNull( L"ull string" );
    
    const wchar_t * pTest = ccbTest ? ccbTest : ccbNull;
    

    没有更多的临时性。

    【讨论】:

      【解决方案2】:

      在您的上述示例中,我没有看到临时 CComBSTR。

      CComBSTR 是一个 RAII 包装类,用于帮助管理 BSTR 的生命周期,当它超出范围时,底层 BSTR 将被销毁。

      ccbTest 是一个自动(堆栈)变量,当它超出范围(在_tmain 末尾)时,它和它管理的 BSTR 将被销毁。

      【讨论】:

      • 请尝试我的代码,调试并进入调用:有一个临时的,即使你没有“看到”它:-)
      猜你喜欢
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      • 2015-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多