[openbeos] Re: B_TRUE/B_FALSE

  • From: Tyler Dauwalder <tyler@xxxxxxxxxxxxx>
  • To: openbeos@xxxxxxxxxxxxx
  • Date: Sun, 21 Sep 2003 14:33:51 -0700

On 2003-09-21 at 03:37:31 [-0700], Ingo Weinhold wrote:
> On 2003-09-21 at 07:21:46 [+0200], Tyler Dauwalder wrote:
> > You could also define a bool_t or a boolstatus_t type that's identical to
> > status_t, but whose use as a return value would flag the function as
> > operating as described above instead of just returning a standard 
> > status_t.
>
> Doesn't sound too bad. bool_t would clash with the equally named RPC type.
> boolstatus_t would be OK with me, but others might find it a bit long -- in
> case that is so, maybe bstatus_t?

Either would work for me.

On 2003-09-21 at 05:11:50 [-0700], Ingo Weinhold wrote:
> Though, now that I think of it, I never liked this return value/error code
> multiplexing. The IMHO straight forward way is to return a status_t and
> pass the data back through a reference parameter. This is more flexible
> anyway, since it works for any data type.

Well, see, here is where we differ :-) :-P. I like the ssize_t return method. 
It's convenient, you still get a standard error code when things go wrong 
that can help point you in the direction of the cause, and there's no 
ambiguity about what any of the return values mean. A reference parameter is 
all of the above, minus convenient, since you have to allocate a bool 
somewhere to pass in as the output parameter. Further, references are so 
non-existent in the Be APIs, pointer output parameters tend to get used 
instead, which means you have to do an extra NULL check in the function 
that's being called. And no, this isn't a terrible amount of work, but it's 
the kind of inconvenience that leads people to just return an overloaded bool.

On 2003-09-21 at 06:38:36 [-0700], Ingo Weinhold wrote:
> > Or use reference paraments like you, and Ingo, said.
> Definitely the best choice. ;-)

From a theoretical standpoint, sure. ;-)

> > (Isn't it unusual for a boolean function to fail, I mean, it's either
> > true or false..
> >  Perhaps it shouldn't have been a boolean in the first place?)
> 
> Well, there are already a couple of ambigious situations. Just take
> BVolume::IsReadOnly for example. If the object isn't properly initialized,
> false is returned, too, but actually that's an error condition. One could
> say, that the caller should invoke InitCheck() before to check whether the
> object is initialized, but even then there's a race condition, if the
> volume is just unmounted inbetween the calls.
> I suspect, that other examples of this kind are equally harmless, though.
> Which is probably why convenience is chosen over correctness.

That's a good point: many of the cases in which people opt for overloading 
the meaning of bool return values are probably relatively harmless. But 
having a true error code in your hands can make finding unexpected bugs 
easier.

On 2003-09-21 at 08:03:54 [-0700], Axel Dörfler wrote:
> Ingo Weinhold <bonefish@xxxxxxxxxxxxxxx> wrote:
> > Though, now that I think of it, I never liked this return value/error
> > code
> > multiplexing. The IMHO straight forward way is to return a status_t
> > and
> > pass the data back through a reference parameter. This is more
> > flexible
> > anyway, since it works for any data type.
> 
> I think that's the best solution - the other would be the use of
> exceptions :-)

I guess my overall train of thought is this: 
1. For trying to write solid code, I don't like functions that can fail that 
don't return an error code.
2. IMO, people will more often opt for overloading the meaning of a bool 
return value than going to the trouble of using an output parameter, both 
because it's more work to implement a function that uses output parameters, 
and more work to use one.
3. Our current policy is "return values, not exceptions (unless absolutely 
necessary)", so exceptions are out.
4. Having B_TRUE/B_FALSE plus bstatus_t or whatever would make it convenient 
to return something in {true,false,error}, while still being unambiguous. The 
same thing is currently done for returning something in {size_t,error} 
through the use of ssize_t return values, which I feel is a relatively 
elegant and practical solution given the issues addressed above.

-Tyler


Other related posts: