在处理HRESULT返回值时,我遇到了一些非常尴尬的事情,看起来成功是0,失败是1.这背后的逻辑是什么?
我真的试过, if(!hr)
,失败悲惨地,浪费了我的生命一小时,直到我找出了实际的成功retval是0.我想打电话给谁认为这是一个白痴的人,但我会尽量冷静希望有人会对这个惯例有所了解。
HRESULT的最初目的是为了防止OS / 2操作系统的不同子系统中的错误代码之间的冲突,正式规定公共和微软内部使用的错误代码范围。
这就是为什么0(HRESULT的最高位)的值意味着“没有错误”,即成功。
但是应该小心,因为HRESULT有可能将最高位设置为0,而将其他位设置为不同于0.这意味着,检查if(0 == hr) { ... }
可能不适用于某些成功案例。 检查成功的正确方法是if(0 <= hr) { ... }
。
维基百科有更详细的信息 。
在处理HRESULT值时,可以使用SUCCEEDED
和FAILED
宏来避免错误。 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
正如你所看到的,这是对自定义错误代码,警告和信息提供非常合理支持的最佳设计之一
您通常应该使用SUCCEEDED
和FAILED
宏来测试HRESULT
因为绝大多数函数为了成功返回S_OK
(value = 0),所以有非零的成功值(例如S_FALSE
)。 通常情况下,您需要在可能返回的情况下明确测试此类值,但在一般情况下,使用SUCCEEDED
会更清晰和更安全。
if (SUCCEEDED(hr)) { // ...