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-expression だけに許可することです (つまり、if (条件) { 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))

たとえば、このlive exampleを参照してください。

ただし、ここでは参照をまったく使用する必要がないことに注意してください。つまり、次のifステートメントも有効であり、への左辺値参照への一時的なバインドを作成するよりも、意図をより適切に表現していますconst

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

たとえば、このlive exampleを参照してください。さらに、上記では を変更する こともできますがselect_image、 への参照では変更できconstません。

于 2013-04-17T14:35:59.083 に答える