Boost logo

Boost :

From: Daryle Walker (darylew_at_[hidden])
Date: 2003-11-27 00:20:57


On 11/24/03 10:47 PM, "Joel de Guzman" <joel_at_[hidden]> wrote:

> David Abrahams <dave_at_[hidden]> wrote:
>> "Joel de Guzman" <joel_at_[hidden]> writes:
>>
>>>> I know that. I was asking about bool_testable. Wasn't that the
>>>> component under discussion? It's a completely different technique,
>>>> IMO.
>>>
>>> I thought so. IMO, it is safe_bool that should get a fast-track
>>> review.
>>
>> safe_bool is an idiom, not a library component. Anyone's already free
>> to use the idiom. I don't think we can review it on that basis.
>
> Hmmm... It would be nice if we had only one implementation somewhere
> in utilities perhaps. A single implementation will help avoid reimplementing
> the same wheel. Yes, it's a simple code, but there are some hidden issues
> such as Borland's inability to grok the member pointer trick.

Well, the safe_bool operator is usually used as the core Boolean routine, so
it fundamentally _cannot_ be provided by a library. All operator helper
classes need an author-provided core routine, so your suggestion would just
move the author-provided code somewhere else.

> IIUC, what you mean is that we do not have to review something like that.
> Ok, but it would still be good to have a single implementation. Spirit uses:

Actually, a single implementation is a _very_ bad idea!

> struct safe_bool_impl
> {
> int* dummy;
> };
>
> typedef int* safe_bool_impl::*safe_bool;
>
> inline safe_bool
> make_safe_bool(bool cond)
> {
> return cond ? &safe_bool_impl::dummy : 0;
> }
>
> and it is used all throughout. Example:
>
> template <typename T>
> inline match<T>::operator safe_bool() const
> {
> return make_safe_bool(len >= 0);
> }
>
> Borland, for one, does not like this code and I had to disable it:
>
> typedef bool safe_bool;
>
> inline safe_bool
> make_safe_bool(bool cond)
> {
> return cond;
> }

The problem is that for EVERY non-composite built-in type, there is a "bool
operator ==(T, T)" generated by the compiler. This means that every type
that shares a safe-bool is (in)equality-comparable with each other via a
single step automatic conversion! You have to fix this by creating == and
!= operators for every type combination, making the combinations that aren't
supposed to be comparable give some sort of compile-time error instead
(a.k.a. "poisoning"). This results in so much pointless busy work that it's
just better to give up and provide separate safe-bool's for each class you
define.

BTW, Spirit does have a solution for this problem, right? Otherwise, you
have a major bug!

(Note that no matter how you define Boolean-conversion, you need to
explicitly provide operators == and != for your type, "poisoned" if such
objects aren't supposed to be comparable, and conventional if they are.)

> Perhaps other people might have a better workaround for Borland.
> In the same vein, perhaps there are other compilers that need
> some more workarounds?

Daryle


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk