6

我在处理 HRESULT 返回值时遇到了一些非常尴尬的事情,似乎成功为 0,失败为 1。这背后的逻辑是什么?

我实际上尝试过if(!hr)并且失败得很惨,浪费了我生命中的一个小时,直到我发现实际成功的 retval 为 0。我想把想到这个的人称为白痴,但我会试着冷静下来——希望有人会阐明这一公约。

4

3 回答 3

16

HRESULT 的最初目的是正式列出供公众和 Microsoft 内部使用的错误代码范围,以防止 OS/2 操作系统的不同子系统中的错误代码发生冲突。

这就是为什么值 0(HRESULT 的最高位)意味着“没有错误”,即成功。

但是应该小心,因为 HRESULT 可能将最高位设置为 0,而其他位设置为不同于 0。这意味着,检查if(0 == hr) { ... }可能不适用于某些成功的情况。检查成功的正确方法是if(0 <= hr) { ... }.

维基百科有更详细的信息

SUCCEEDEDFAILED宏可用于在处理 HRESULT 值时避免错误。if(0 <= hr) { ... }if(SUCCEEDED(hr)) { ... }基本上是一样的东西。

于 2012-10-12T05:15:27.433 回答
4

你又误会了,因为几乎所有系统中的所有系统错误,返回值 0 都是成功,非零返回值表示错误代码,使用这种技术,我们可以只用一个返回值报告不同类型的错误。但是因为HRESULT我们有>= 0成功和<0错误,所以从角度来看,1 的值HRESULT是成功而不是错误。HRESULT>0 表示警告或有关功能的信息,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

如您所见,这是对自定义错误代码、警告和信息提供非常合理的支持的最佳设计之一

于 2012-10-12T05:22:58.677 回答
1

您通常应该使用SUCCEEDEDandFAILED宏来测试HRESULTs,因为虽然绝大多数函数返回S_OK(value = 0) 表示成功,但也有一些非零成功值(例如S_FALSE)。通常,您需要明确地测试这些值,以防它们可能被返回,但在一般情况下,使用SUCCEEDED更清晰、更安全。

if (SUCCEEDED(hr)) { // ...
于 2012-10-12T06:03:41.100 回答