[openbeos] Re: B_TRUE/B_FALSE

  • From: Tyler Dauwalder <tyler@xxxxxxxxxxxxx>
  • To: openbeos@xxxxxxxxxxxxx
  • Date: Mon, 22 Sep 2003 01:04:28 -0700

On 2003-09-21 at 16:25:20 [-0700], Axel Dörfler wrote:
> Tyler Dauwalder <tyler@xxxxxxxxxxxxx> wrote:
> > Well, see, here is where we differ :-) :-P. I like the ssize_t return
> > method.
> 
> I also don't like it too much - mostly, because it often hides a
> possible bug in the implementation as in:
> ssize_t read(char *buffer, size_t bufferSize);
> bufferSize must not have the upper bit set, or else this function would
> have problems returning the correct value. I think that's certainly
> confusing.

That's a good point, but it's also not a problem in the boolean domain.

> > 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.
> 
> Sure, but there is no point in *not* using reference parameters - most
> of the time, they are better suited for that kind of job anyway.

Oh, I definitely agree; just making an observation as to another reason 
output parameters end up being more work. :-)

> > 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.
> 
> Yes, it might not be a bad idea - but I think the approach using a
> reference parameter is cleaner most of the time.
> If it would be used for comparison once only, the boolstatus_t would be
> a convenient way. Often, though, those values would have to be stored
> for later use, and I would really hate code like this:
> 
> boolstatus_t resizeStatus = partition->IsResizable();
> if (resizeStatus < B_OK)
>     return resizeStatus;
> 
> if (resizeStatus == B_TRUE)
>     isResizable = true;
> else
>     isResizable = false;
> ...

Well, "isResizable = resizeStatus == B_TRUE;" works just as well. :-P

> In that case, I would rather like to see:
> 
> status_t status = partition->IsResizable(isResizable);
> if (status < B_OK)
>     return status;
> 
> with an optional "&" before the isResizable :-)

But that's even nicer yet. :-)

At any rate, your example prompted me to do some more concrete analysis of 
the matter, which perhaps I should have done in the first place. :-) I 
figure there are three main ways functions that return a boolean value are 
used. I wrote out versions of each of the cases to see what they looked 
like, and if anyone cares, they're at the end of the message.

1. One truth assignment is treated as success, the other, failure without 
any sort of error code. Returning a bool works well here, as does 
bstatus_t. Using a reference parameter is pretty ugly, but as I've argued 
before, I don't like this case in the first place, owing to not having (or 
ignoring) any error code, so it's moot.

2. The boolean value is used to branch once and only once, assuming no 
error occurs. bstatus_t is a little shorter here than the reference 
parameter version, but not necessarily any cleaner. Returning a bool is, of 
course, right out.

3. The boolean value needs to be stored and used later. Assuming you assign 
like I did above instead of inside an if-then-else statement, the bstatus_t 
version is the same length as the reference parameter version, but
the reference version is arguably cleaner (and further requires no 
additional work beyond case 2).

So anyway, I'm sold on references now. I'll back off. :-)

-Tyler

//---------------------------------------------------------
// prototypes
//---------------------------------------------------------

bool get_bool(...);                    // bool
bstatus_t get_bool(...);               // bstatus_t
status_t get_bool(bool &result, ...);  // ref

//---------------------------------------------------------
// case 1
//---------------------------------------------------------

// bool
if (get_bool(...)) {
        // do stuff
} else {
        // error, but no error code
}

// bstatus_t
if (get_bool(...) == B_TRUE) {
        // do stuff
} else {
        // error, but no error code
}

// ref
bool boolValue;
if (get_bool(boolValue, ...) >= B_OK && boolValue) {
        // do stuff
} else {
        // error, but no error code
}

//---------------------------------------------------------
// case 2
//---------------------------------------------------------

// bool
if (get_bool(...)) {
        // do true stuff
} else {
        // do false stuff, or maybe error...?
}

// bstatus_t
result = get_bool(...);
if (result >= B_OK) {
        if (result == B_TRUE) {
                // do true stuff
        } else {
                // do false stuff
        }
} else {
        // error
}

// ref
bool boolValue;
result = get_bool(boolValue, ...);
if (result >= B_OK) {
        if (boolValue) {
                // do true stuff
        } else {
                // do false stuff
        }
} else {
        // error
}

//---------------------------------------------------------
// case 3
//---------------------------------------------------------

// bool
bool boolValue = get_bool(...);
if (boolValue) {
        // do true stuff
} else {
        // do false stuff, or maybe error...?
}

// bstatus_t
result = get_bool(...);
if (result >= B_OK) {
        bool boolValue = result == B_TRUE;
        if (boolValue) {
                // do true stuff
        } else {
                // do false stuff
        }
} else {
        // error
}

// ref
bool boolValue;
result = get_bool(boolValue, ...);
if (result >= B_OK) {
        if (boolValue) {
                // do true stuff
        } else {
                // do false stuff
        }
} else {
        // error
}



Other related posts: