S_OK and S_FALSE return code differentiation 
Author Message
 S_OK and S_FALSE return code differentiation

Hello:

COM server returns S_OK or S_FALSE codes depending on
connection status. COM-client needs to differentiate
return codes. However SUCCEED(hr) is true for both
S_OK and S_FALSE. What is recommended method for making
client see return codes differently?

There is also second question. COM-server making connection
by WinSock function. I found out that "connect" function
returns very slowly ( 20-30 sec ) if IP/Port provided is
wrong. What is a fast and recommended method for checking
status of connection?

Thank you!



Sun, 22 Feb 2004 06:15:06 GMT  
 S_OK and S_FALSE return code differentiation
I can posture about your first question, I have no knowledge regarding the
second.

The two successful HRESULT values, S_OK and S_FALSE typically have no
practical difference when people program using COM objects. A COM function
should return either S_OK, or one of the E_ codes. Here is an example of why
S_FALSE should never be used.
 // Some COM object function
 HRESULT CMyCoClass::Foo(/*[out, retval]*/ISomePointer** pPointer)
 {
     if (pPointer == NULL)
         return E_POINTER;

     HRESULT hr = S_OK;
 ..
 ..
     if (nCount < 0)
     {
         hr = S_FALSE;
     }
 ..
 ..
      return hr;
 }

 // Now, the bit of code where someone uses this function
    if (SUCCEEDED(mObj->Foo(&pPointer))
    {
         // do something
    }
    else // failed to use COM Object
    {
        // Gracefully degrade
    }

Now, in both S_OK and S_FALSE, the SUCCEEDED macro will return TRUE. The
original COM object programmer was trying to convey some information back to
the user by returning S_FALSE, but that information, in typical COM object
usage, is lost in the SUCCEEDED macro. And  how many COM object users do you
see use this bit of code:

 hr = mObj->Foo(&pPointer);
 if (hr == S_OK)
 {
     // do something
 }
 else if (hr == S_FALSE) // S_FALSE
 {
     // Handle this situation
 }
 else if (hr < 0) // all E_CODES are negative
 {
     // gracefully degrade
 }
 else // Ok, something weird has happened
 {
     // gracefully degrade again
 }

I have never seen anyone do that much HRESULT checking, because they are
using the SUCCEEDED (or something similar) macro to do that validation, but
the SUCCEEDED macro only checks hr >= 0. The information of S_FALSE is lost.

Besides, what does S_FALSE mean? I Succeeded, but I failed? How is that
information useful? Interpreted? I have heard that Microsoft has  said that
S_FALSE was a mistake and should not be used. I agree! :)

If you want to pass data back to the client, pass a pointer to a
VARIANT_BOOL as one of the function parameters and have the COM server set
this value when the need arises. If you do not have access to the server
code, you will have to check for S_FALSE explicitly as per the above
example.

 I've had a couple long discussions in regard to this issue, and I hope that
I've done it justice in a written format.

Dave White
http://www.slb.com


Quote:
> Hello:

> COM server returns S_OK or S_FALSE codes depending on
> connection status. COM-client needs to differentiate
> return codes. However SUCCEED(hr) is true for both
> S_OK and S_FALSE. What is recommended method for making
> client see return codes differently?

> There is also second question. COM-server making connection
> by WinSock function. I found out that "connect" function
> returns very slowly ( 20-30 sec ) if IP/Port provided is
> wrong. What is a fast and recommended method for checking
> status of connection?

> Thank you!



Sun, 22 Feb 2004 09:02:08 GMT  
 S_OK and S_FALSE return code differentiation

Quote:
>The two successful HRESULT values, S_OK and S_FALSE typically have no
>practical difference when people program using COM objects.

Come on, stop talking crap. S_FALSE is used all over COM, especially in OLE
protocols. You simply check for the specific code, rather than use the
SUCCEEDED() or FAILED() macros. Code often distinguishes between lots of
different error codes, as well as success codes, they are not just for
de{*filter*}s.

There is nothing wrong with

if (hr==S_FALSE) or if (hr==S_OK)

or even

switch (hr)
{
case S_OK:
    (...)
    break;
case S_FALSE:
    (...)
    break;
case E_OUTOFMEMORY:
    (...) do different error handling for memory problems...
    break;
default:
    (...)
    break;

Quote:
}
>Besides, what does S_FALSE mean? I Succeeded, but I failed? How is that
>information useful? Interpreted? I have heard that Microsoft has  said that
>S_FALSE was a mistake and should not be used. I agree! :)

S_FALSE means that the function succeeded, but returned false. It is a
method of using the HRESULT to return a boolean variable without requiring
an additional parameter on the interface function. For example, an interface
function such as FileExists() might return S_OK or S_FALSE to indicate
whether it exists or not. If the function failed, then it might return
E_FAIL. It is much cleaner in C++, because you don't need to set up a local
variable and return its pointer, making the code more readable.

The only reason not to use it is because Visual Basic is so brain dead that
it can't handle it. Why it doesn't just turn it into VARIANT_BOOL and cope
with it, I don't know. Generally speaking I can't be bothered to jump though
Visual Basic's hoops, such as only being allowed to use about three
hopelessly bloated data types.

So basically, if you are using OLE automation for scripts and VB, by all
means don't use S_FALSE. If you are doing proper complicated OLE programming
which VB is too basic to implement anyway, then go ahead. It is much nicer
to use in C++.

An example (one of hundreds) of an OLE protocol returning S_FALSE:

IOleInPlaceSiteWindowless::CanWindowlessActivate

Informs an object if its container can support it as a windowless object
that can be in-place activated.

HRESULT CanWindowlessActivate(void);
Return Values
S_OK
The object can activate in place without a window.
Remarks
If this method returns S_OK, the container can dispatch events to it using
IOleInPlaceObjectWindowless.
If this method returns S_FALSE, the object should create a window and behave
as a normal compound document object.

Christian.



Sun, 22 Feb 2004 17:13:41 GMT  
 S_OK and S_FALSE return code differentiation
Be aware that VB and scripting clients don't distinguish between S_OK
and S_FALSE (and other SUCCEEDED() return values). So if your control
will be used by a variety of clients, then I recommend using just S_OK
and error returns.

Chris



Sun, 22 Feb 2004 18:27:51 GMT  
 S_OK and S_FALSE return code differentiation

Quote:
> COM server returns S_OK or S_FALSE codes depending on
> connection status. COM-client needs to differentiate
> return codes. However SUCCEED(hr) is true for both
> S_OK and S_FALSE. What is recommended method for making
> client see return codes differently?

Erm, (S_OK == hr) and (S_FALSE == hr) seem to do the trick in C++

In VB (and in C++ using #import-ed smart pointers if you don't use
raw_[methodname]) you're screwed.

You're usually better of having an [out,retval] VARIANT_BOOL parameter
instead of depending on S_OK and S_FALSE.

Mark



Sun, 22 Feb 2004 19:03:31 GMT  
 S_OK and S_FALSE return code differentiation
I know that you can check for the specific error codes. (I had a very simple
example explaining that). How many programmers do you know that do all that
HRESULT checking, or how many just reach into the macro tool box and pull
out SUCCEEDED and FAILED?

In our organization, people did not realize that SUCCEEDED didn't catch
S_FALSE. All they see is "FALSE" and expect that means failure (as in most
other places), not "Succeeded but failed".  I feel the primary purpose of
HRESULTs is to pass back information to handle errors in COM. That is why
there are so many E_* results, and 2 S_* results. Yes, you can use the S_OK
and S_FALSE as a "success" AND a boolean but now you are using the same
variable (hr) for two purposes. If you are building a black box COM object
you have to consistently document this behavior and consistently ensure that
anyone using your object reads the documentation, OR, you can make the code
self-documenting by removing the "interpret-the-meaning-yourself" nature of
S_FALSE by not using it, and using a VARIANT_BOOL to pass back the
out-of-bounds information regarding the funtion call.

Cheers,
Dave White
http://www.*-*-*.com/


Quote:
> >The two successful HRESULT values, S_OK and S_FALSE typically have no
> >practical difference when people program using COM objects.

> Come on, stop talking crap. S_FALSE is used all over COM, especially in
OLE
> protocols. You simply check for the specific code, rather than use the
> SUCCEEDED() or FAILED() macros. Code often distinguishes between lots of
> different error codes, as well as success codes, they are not just for
> de{*filter*}s.

> There is nothing wrong with

> if (hr==S_FALSE) or if (hr==S_OK)

> or even

> switch (hr)
> {
> case S_OK:
>     (...)
>     break;
> case S_FALSE:
>     (...)
>     break;
> case E_OUTOFMEMORY:
>     (...) do different error handling for memory problems...
>     break;
> default:
>     (...)
>     break;
> }

> >Besides, what does S_FALSE mean? I Succeeded, but I failed? How is that
> >information useful? Interpreted? I have heard that Microsoft has  said
that
> >S_FALSE was a mistake and should not be used. I agree! :)

> S_FALSE means that the function succeeded, but returned false. It is a
> method of using the HRESULT to return a boolean variable without requiring
> an additional parameter on the interface function. For example, an
interface
> function such as FileExists() might return S_OK or S_FALSE to indicate
> whether it exists or not. If the function failed, then it might return
> E_FAIL. It is much cleaner in C++, because you don't need to set up a
local
> variable and return its pointer, making the code more readable.

> The only reason not to use it is because Visual Basic is so brain dead
that
> it can't handle it. Why it doesn't just turn it into VARIANT_BOOL and cope
> with it, I don't know. Generally speaking I can't be bothered to jump
though
> Visual Basic's hoops, such as only being allowed to use about three
> hopelessly bloated data types.

> So basically, if you are using OLE automation for scripts and VB, by all
> means don't use S_FALSE. If you are doing proper complicated OLE
programming
> which VB is too basic to implement anyway, then go ahead. It is much nicer
> to use in C++.

> An example (one of hundreds) of an OLE protocol returning S_FALSE:

> IOleInPlaceSiteWindowless::CanWindowlessActivate

> Informs an object if its container can support it as a windowless object
> that can be in-place activated.

> HRESULT CanWindowlessActivate(void);
> Return Values
> S_OK
> The object can activate in place without a window.
> Remarks
> If this method returns S_OK, the container can dispatch events to it using
> IOleInPlaceObjectWindowless.
> If this method returns S_FALSE, the object should create a window and
behave
> as a normal compound document object.

> Christian.



Sun, 22 Feb 2004 20:56:29 GMT  
 S_OK and S_FALSE return code differentiation

Quote:
> And  how many COM object users do you
> see use this bit of code:

>  hr = mObj->Foo(&pPointer);
>  if (hr == S_OK)
>  {
>      // do something
>  }
>  else if (hr == S_FALSE) // S_FALSE
>  {
>      // Handle this situation
>  }

It depends on the definition of the function's interface. If it's documented
to return S_FALSE, then you have to deal with that. One example would be a
function of mine called GetClientExists(). This can return S_OK (the client
exists), S_FALSE (the client doesn't exist) or an error (the client not
existing is not an error!).

Now, to make this function more Automation-friendly, I will eventually
change this to return the existence in an out parameter. But for just C++,
S_FALSE was a reasonable return value.



Mon, 23 Feb 2004 00:54:07 GMT  
 S_OK and S_FALSE return code differentiation
Your basic misconception is that HRESULT returns _errors_. No, it
returns STATUS!!! There are many successful HRESULTs, not just
S_OK and S_FALSE. Consider: DB_S_BOOKMARKSKIPPED, DB_S_ENDOFROWSET,
and DB_S_STOPLIMITREACHED all taken from a single method -
IRowsetLocate::GetRowsAt from the OLE DB documentation. I
picked it at random from the OLE DB docs BTW...

This said, it's true that in Automation HRESULT is degraded to
error code. But COM is _not_ Automation!

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD

MVP VC FAQ: http://www.*-*-*.com/
=====================================


Quote:
> I know that you can check for the specific error codes. (I had a very
simple
> example explaining that). How many programmers do you know that do all
that
> HRESULT checking, or how many just reach into the macro tool box and pull
> out SUCCEEDED and FAILED?

> In our organization, people did not realize that SUCCEEDED didn't catch
> S_FALSE. All they see is "FALSE" and expect that means failure (as in most
> other places), not "Succeeded but failed".  I feel the primary purpose of
> HRESULTs is to pass back information to handle errors in COM. That is why
> there are so many E_* results, and 2 S_* results. Yes, you can use the
S_OK
> and S_FALSE as a "success" AND a boolean but now you are using the same
> variable (hr) for two purposes. If you are building a black box COM object
> you have to consistently document this behavior and consistently ensure
that
> anyone using your object reads the documentation, OR, you can make the
code
> self-documenting by removing the "interpret-the-meaning-yourself" nature
of
> S_FALSE by not using it, and using a VARIANT_BOOL to pass back the
> out-of-bounds information regarding the funtion call.

> Cheers,
> Dave White
> http://www.*-*-*.com/



> > >The two successful HRESULT values, S_OK and S_FALSE typically have no
> > >practical difference when people program using COM objects.

> > Come on, stop talking crap. S_FALSE is used all over COM, especially in
> OLE
> > protocols. You simply check for the specific code, rather than use the
> > SUCCEEDED() or FAILED() macros. Code often distinguishes between lots of
> > different error codes, as well as success codes, they are not just for
> > de{*filter*}s.

> > There is nothing wrong with

> > if (hr==S_FALSE) or if (hr==S_OK)

> > or even

> > switch (hr)
> > {
> > case S_OK:
> >     (...)
> >     break;
> > case S_FALSE:
> >     (...)
> >     break;
> > case E_OUTOFMEMORY:
> >     (...) do different error handling for memory problems...
> >     break;
> > default:
> >     (...)
> >     break;
> > }

> > >Besides, what does S_FALSE mean? I Succeeded, but I failed? How is that
> > >information useful? Interpreted? I have heard that Microsoft has  said
> that
> > >S_FALSE was a mistake and should not be used. I agree! :)

> > S_FALSE means that the function succeeded, but returned false. It is a
> > method of using the HRESULT to return a boolean variable without
requiring
> > an additional parameter on the interface function. For example, an
> interface
> > function such as FileExists() might return S_OK or S_FALSE to indicate
> > whether it exists or not. If the function failed, then it might return
> > E_FAIL. It is much cleaner in C++, because you don't need to set up a
> local
> > variable and return its pointer, making the code more readable.

> > The only reason not to use it is because Visual Basic is so brain dead
> that
> > it can't handle it. Why it doesn't just turn it into VARIANT_BOOL and
cope
> > with it, I don't know. Generally speaking I can't be bothered to jump
> though
> > Visual Basic's hoops, such as only being allowed to use about three
> > hopelessly bloated data types.

> > So basically, if you are using OLE automation for scripts and VB, by all
> > means don't use S_FALSE. If you are doing proper complicated OLE
> programming
> > which VB is too basic to implement anyway, then go ahead. It is much
nicer
> > to use in C++.

> > An example (one of hundreds) of an OLE protocol returning S_FALSE:

> > IOleInPlaceSiteWindowless::CanWindowlessActivate

> > Informs an object if its container can support it as a windowless object
> > that can be in-place activated.

> > HRESULT CanWindowlessActivate(void);
> > Return Values
> > S_OK
> > The object can activate in place without a window.
> > Remarks
> > If this method returns S_OK, the container can dispatch events to it
using
> > IOleInPlaceObjectWindowless.
> > If this method returns S_FALSE, the object should create a window and
> behave
> > as a normal compound document object.

> > Christian.



Mon, 23 Feb 2004 02:03:49 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. Return S_OK, S_FALSE

2. MovePrev always returns S_OK??

3. how to detect S_FALSE from VB client?

4. S_OK and S_FAIL from unmanaged COM?

5. Info needed: Numerical Differentiation in C/C++

6. Numerical Differentiation in C/C++

7. Automatic Differentiation

8. IActiveDesktop::SetWallpaper always returns S_OK even when it fails.

9. Fread returns 0, ferror returns 0, feof returns 16

10. Not all code paths return a value

11. Return codes from console apps

12. LogonUser always returns error code 126

 

 
Powered by phpBB® Forum Software