HRESULT の戻り値を操作しているときに、非常に厄介なことに遭遇しました。成功は 0 で、失敗は 1 のようです。この背後にあるロジックは何ですか?
私は実際に試してみif(!hr)
て惨めに失敗し、実際の成功の retval が 0 であることがわかるまで、1 時間の人生を無駄にしました。この慣習に光を当てます。
HRESULT の本来の目的は、OS/2 オペレーティング システムのさまざまなサブシステムでのエラー コード間の衝突を防ぐために、エラー コードの範囲を公的および Microsoft 内部で使用するために正式にレイアウトすることでした。
そのため、値 0 (HRESULT の最上位ビット) は「エラーなし」、つまり成功を意味します。
ただし、HRESULT の最上位ビットが 0 に設定され、他のビットが 0 以外に設定される可能性があるため、注意が必要if(0 == hr) { ... }
です。成功を確認する正しい方法はif(0 <= hr) { ... }
.
ウィキペディアには、より詳細な情報があります。
SUCCEEDED
また、FAILED
マクロを使用して、HRESULT 値を処理する際のミスを回避できます。if(0 <= hr) { ... }
とif(SUCCEEDED(hr)) { ... }
基本的に同じものです。
もう一度誤解しています。ほとんどすべてのシステムのすべてのシステムエラーの戻り値0は成功であり、ゼロ以外の戻り値はエラーコードを示します。この手法を使用すると、1つの戻り値でさまざまな種類のエラーを報告できます。しかし、HRESULT
私たち>= 0
は成功と<0
エラーのために持っているので、の観点からの1の値はHRESULT
、エラーではなく成功です。> 0はHRESULT
機能に関する警告または情報を示し、0は絶対的な成功を意味し、<0はエラーを示します。HRESULTのレイアウトは次のとおりです。
3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+-+-+-+-+-+---------------------+-------------------------------+
|S|R|C|N|r| Facility | Code |
+-+-+-+-+-+---------------------+-------------------------------+
where
S - Severity - indicates success/fail
0 - Success
1 - Fail (COERROR)
R - reserved portion of the facility code, corresponds to NT's second severity bit.
C - reserved portion of the facility code, corresponds to NT's C field.
N - reserved portion of the facility code. Used to indicate a mapped NT status value.
r - reserved portion of the facility code. Reserved for internal use. Used to
indicate HRESULT values that are not status values, but are instead message
ids for display strings.
Facility - is the facility code
Code - is the facility's status code
ご覧のとおり、これはカスタムエラーコード、警告、および情報を非常に合理的にサポートする最高の設計の1つです。
通常、SUCCEEDED
とFAILED
マクロを使用してHRESULT
s をテストする必要があります。これは、大部分の関数が成功に対して (値 = 0) を返しS_OK
ますが、ゼロ以外の成功値 ( などS_FALSE
) があるためです。多くの場合、そのような値が返される可能性がある場合は明示的にテストする必要がありますが、一般的なケースでは、使用するSUCCEEDED
方が明確で安全です。
if (SUCCEEDED(hr)) { // ...