Re: HRESULT
"June Lee" <iiuu66@yahoo.com> ha scritto nel messaggio
news:4gulu3prunl23jd6fvvihal7ps73kef8j6@4ax.com...
is HRESULT only used in COM interface programming?
I see this quite often in a COM module call.
To add to what others correctly wrote, I would like to suggest you to use
HRESULT only in COM code or ATL development (e.g. if you are developing a
COM component).
One of COM requirements was that it must support several languages,
including C. And C has no exception mechanism for error handling (instead,
you can use exceptions in C++). So, to be compatible also with C, in COM
every error condition is signaled returning HRESULT.
This may lead to some problems in "quality" of code, for example, in typical
COM code, you may have:
<code>
HRESULT SomeFunction(...)
{
// erorr code
HRESULT hr;
...
hr = pX->DoSomething(...);
if ( FAILED(hr) )
... cleanup
return hr;
hr = pY->DoSomethingElse(...);
if ( FAILED(hr) )
... cleanup
return hr;
...
...
// Everything OK
return S_OK;
}
</code>
The problem is duplicating "cleanup".
To avoid duplicating cleanup code in each "if ( FAILED(hr)) ..." branch,
'goto' statements may be used, e.g.:
<code>
hr = pX->DoSomething(...);
if ( FAILED(hr) )
goto ErrorCleanup;
hr = pY->DoSomethingElse(...);
if ( FAILED(hr) )
goto ErrorCleanup;
...
// All right
return S_OK;
// *** CLEANUP [on error] ***
ErrorCleanup:
// Do cleanup here...
...
// Return error code
return hr;
</code>
The above code could be simplified if some quality tools are used, like
smart pointers (like CComPtr COM smart pointer template; in fact, smart
pointers do proper cleanup, like calling IUnknown::Release, when the smart
pointer goes out of scope; so, in that case, returning an error code could
be fine, without explicit cleanup: the smart pointer will do the cleanup
automatically).
However, if you are not targeting COM interface programming, and e.g. you
are doing "pure" C++ (or even MFC programming), I would suggest you to *not*
use HRESULTs.
At least, I would define custom enum for error codes, these are more
readable than HRESULTs, IMHO.
e.g.
<code>
class Something
{
public:
enum ErrorCode
{
Ok = 0, // All right
MemoryFailure,
CantOpenFile,
...
};
// Better custom error code enum than HRESULT
ErrorCode DoSomething(...);
};
</code>
Or you may also consider using C++ exceptions (and use RAII pattern, to
develop exception-safe code).
Giovanni