这个模式在c++中工作吗?

Does this pattern work in C++?

本文关键字:工作 c++ 模式      更新时间:2023-10-16

我在我的项目上运行PREfast静态代码分析,它给了我C6001 '使用未初始化内存'错误:

// 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是错的吗?或者这里有一些微妙的东西使我的上述代码和假设不正确?

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的引用则不能。