2

我正在我的项目上运行 PREfast 静态代码分析,它给了我 C6001 'using uninitialized memory' 这种模式的错误:

// AutoSelectGDIObject is a class
if (AutoSelectGDIObject & select_image = AutoSelectGDIObject(hDCImgSource, hBmp))
{
   // use hDCImgSource knowing that hBmp is selected into it
}
// now we are guaranteed that hDCImgSource has had hBmp removed and its previous bmp re-selected into itself

我试图利用的技巧是允许 select_image 的范围仅限于 if 表达式(即 if (condition) { expression-block = 条件变量的生命周期}。

VS 已经愉快地编译(并且可能会运行它)很长一段时间了。我已经很久没有这样的单步代码了,但据我所知,如果 select_image 的运算符 bool() 返回 true,它只会进入 if 块,并且在退出 if 块时会破坏 select_image 的实例。

PREfast 错了吗?或者这里有什么微妙的东西使我上面的代码和假设不正确?

4

1 回答 1

4

PREfast 错了吗?或者这里有什么微妙的东西使我上面的代码和假设不正确?

该代码是无效的 C++,但 VC 会编译它,因为它允许作为文档化扩展,将对非const限定类型的左值引用绑定到临时对象。

在我看来,这是一个愚蠢的扩展。根据 C++ 标准,临时对象只能被绑定到左值引用const或右值引用(在这种情况下,它们的生命周期超出了创建它们的完整表达式的末尾)。

因此,你的if陈述应该是:

if (AutoSelectGDIObject const& select_image = 
//                      ^^^^^
                               AutoSelectGDIObject(hDCImgSource, hBmp))

例如,参见这个活生生的例子

但是请注意,您根本不需要在此处使用引用。换句话说,以下if语句也是有效的,并且比创建对左值引用的临时绑定更好地表达了您的意图const

if (AutoSelectGDIObject select_image = AutoSelectGDIObject(hDCImgSource, hBmp))

例如,参见这个活生生的例子。此外,上面还允许您修改 select_image,而对 的引用const则不允许。

于 2013-04-17T14:35:59.083 回答