我在使用HRESULT返回值时遇到了一些非常尴尬的事情,似乎成功是0而失败是1.这背后的逻辑是什么?
我实际上尝试了if(!hr)
并且失败了,浪费了我生命中的一小时,直到我发现实际的成功retval是0.我想称那个认为这个白痴的人,但我会试着冷静下来 - 希望有人能对这个惯例有所了解。
答案 0 :(得分:11)
HRESULT的最初目的是正式布局公共和Microsoft内部使用的错误代码范围,以防止OS / 2操作系统的不同子系统中的错误代码之间发生冲突。
这就是为什么,0(HRESULT的最高位)的值意味着“没有错误”,即成功。
但是应该注意,因为HRESULT可能将最高位设置为0而其他位设置为0.这意味着,检查if(0 == hr) { ... }
可能不适用于某些成功案例。检查成功的正确方法是if(0 <= hr) { ... }
。
维基百科有more detailed information。
在处理HRESULT值时,可以使用 SUCCEEDED
和FAILED
宏来避免错误。 if(0 <= hr) { ... }
和if(SUCCEEDED(hr)) { ... }
基本相同。
答案 1 :(得分:4)
您再次犯错,因为几乎所有系统中的所有系统错误都返回值为0成功且非零返回值表示错误代码,使用此技术我们可以仅使用一个返回值报告不同类型的错误。但是对于HRESULT
我们有>= 0
表示成功,<0
表示错误,因此HRESULT
视图中的值1是成功而不是错误。在HRESULT
&gt; 0中表示关于功能的警告或信息,0表示绝对成功,而&lt; 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
正如您所看到的,这是最好的设计之一,非常合理地支持自定义错误代码,警告和信息
答案 2 :(得分:0)
您通常应使用SUCCEEDED
和FAILED
宏来测试HRESULT
,因为尽管绝大多数函数返回S_OK
(值= 0)才能成功,有非零成功值(例如S_FALSE
)。通常,您需要在可能返回的情况下明确地测试这些值,但在一般情况下使用SUCCEEDED
更清晰,更安全。
if (SUCCEEDED(hr)) { // ...