为什么HRESULT 0成功?

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

我真的试过, if(!hr) ,失败悲惨地,浪费了我的生命一小时,直到我找出了实际的成功retval是0.我想打电话给谁认为这是一个白痴的人,但我会尽量冷静希望有人会对这个惯例有所​​了解。

HRESULT的最初目的是为了防止OS / 2操作系统的不同子系统中的错误代码之间的冲突,正式规定公共和微软内部使用的错误代码范围。

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

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

维基百科有更详细的信息 。

在处理HRESULT值时,可以使用SUCCEEDEDFAILED宏来避免错误。 if(0 <= hr) { ... }if(SUCCEEDED(hr)) { ... }基本上是相同的东西。

你又错了,因为在几乎所有系统中的所有系统错误返回值0是成功的,非零返回值表示一个错误代码,使用这种技术,我们可以报告不同类型的错误,只有一个返回值。 但是对于HRESULT我们有>= 0的成功和<0的错误,所以从HRESULT的观点1的值是成功的不是一个错误。 在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 

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

您通常应该使用SUCCEEDEDFAILED宏来测试HRESULT因为绝大多数函数为了成功返回S_OK (value = 0),所以有非零的成功值(例如S_FALSE )。 通常情况下,您需要在可能返回的情况下明确测试此类值,但在一般情况下,使用SUCCEEDED会更清晰和更安全。

 if (SUCCEEDED(hr)) { // ...