2

より大きなプロジェクト (Mozilla Firefox 用の ff ActiveX プラグイン) の一部として、次のコード スニペットがあります。

if (CombineRgn(hrgnClip, hrgnClip, hRGN, RGN_AND) != ERROR)
{
        ::InvalidateRgn(m_hWndParent, hrgnClip, fErase);
}

VS2012 でビルドすると、「エラー C2065: 'エラー' : 宣言されていない識別子」エラーが wingdi.h で次のように定義されます。

...
/* Region Flags */
#define ERROR               0  // it wont build when this macro is used
#define NULLREGION          1  // it builds when this macro is used
#define SIMPLEREGION        2
#define COMPLEXREGION       3
#define RGN_ERROR ERROR
...

奇妙なことに、上記のifステートメントで ERROR (正常にビルドされるかどうかを確認するためだけに) を NULLREGION または SIMPLEREGION (同じファイル内のマクロで、問題のあるマクロの 2 行下) に置き換えると、コードは正常にビルドされます。ERROR を使用すると、コードがビルドされません。上記で定義された ERROR マクロが、Visual Studio によって何らかのキーワードや別のマクロなどによってマスクされる可能性はありますか?

4

1 に答える 1

3

ここでの問題は、コンパイル エラー メッセージに ERROR が実際に表示されることです。これは発生しないはずです。プリプロセッサはそれを 0 に置き換えているはずです。

したがって、windows.h の後に #include した .h ファイルのどこかで、一部のプログラマーがマクロ名の競合問題への 10 秒のショートカットを利用して、次のように記述しました。

  #undef ERROR

その行を見つけて削除する必要があります。それはあなたが所有していないファイルであり、将来更新される可能性があり、その変更を何度も何度も行う必要があるため、困難であり、メンテナンスの頭痛の種になる可能性があります。別の方法は、自分で再定義することです。

#define MYGDIERROR 0
...
if (CombineRgn(hrgnClip, hrgnClip, hRGN, RGN_AND) != MYGDIERROR)
//etc...

それでもメンテナンスの問題が発生し、CombineRgn() の戻り値の定義が決して変更されないことに賭ける必要があります。それは非常に安全な賭けです.GDIは石に投げ込まれています.

于 2013-05-31T08:34:48.750 に答える