这种模式是否适用于C ++?

时间:2013-04-17 14:31:21

标签: c++ c++11 static-analysis c++98 prefast

我正在我的项目上运行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-expression(即if(condition){expression-block =条件变量的生命周期}。

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

PREfast错了吗?或者是否有一些微妙的东西使我的上述代码和假设不正确?

1 个答案:

答案 0 :(得分:4)

  

PREfast错了吗?或者是否有一些微妙的东西使我的上述代码和假设不正确?

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

在我看来,这是一个愚蠢的延伸。根据C ++标准,临时数只能绑定到const的左值引用或rvalue引用(在这种情况下,它们的生命周期延伸到创建它们的完整表达式的末尾之外)。

因此,您的if声明应为:

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

例如,请参阅此live example

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

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

例如,请参阅此live example。此外,上述内容还允许您修改 select_image,而对const的引用则不会。