我正在我的项目上运行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错了吗?或者是否有一些微妙的东西使我的上述代码和假设不正确?
答案 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
的引用则不会。