Topic: boolean function parameters


Author: pavel_vozenilek@yahoo.co.uk ("Pavel Vozenilek")
Date: Fri, 10 Jun 2005 22:35:48 GMT
Raw View
It is recommended to use named enum values
instead of bool parameters in functions:

// rather discouraged
void foo(bool show);
.
foo(false);   // what the false means here?


// encouraged
enum { DoNotShow, DoShow } show_t;
void foo(show_t show);
.
foo(DoNotShow);


Disadvantages are:
* the enum is visible in the whole class or namespace
* additional definition is needed, the code gets less readable
* it is bit fragile:
   - it is not immediatelly clear the enum represents bool value
   - one can too easily change enum value like:
    enum { DoNotShow = 1, DoShow };



If one could mix both of approaches and use something
as "named bool":

void foo(bool enum { DoNotShow, DoShow} show)
{
    if (show) ...
}

.
foo(DoNotShow);

then these symbolic values could be local to function,
compiler would be able to ensure there are exactly
two symbols and that their values are 0/1.
Bool enum would be convertible to bool and vice versa.


After implementing chain of functions passing
bool emulating enums across multiple classes
I wish something like that existed.

/Pavel


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Me" <anti_spam_email2003@yahoo.com>
Date: 11 Jun 2005 06:10:05 GMT
Raw View
> It is recommended to use named enum values
> instead of bool parameters in functions:
>
> // rather discouraged
> void foo(bool show);
> .
> foo(false);   // what the false means here?

This is a poor example. The only time booleans get confusing in real
code is when you use double negatives (or worse, triple negatives) or
there are multiple bool parameters.

> Disadvantages are:
> * the enum is visible in the whole class or namespace

namespace foo
{
 enum foo { a, b };
}

void a(foo::foo val = foo::a);

it also works with by replacing namespace with struct/class (I'd
recommend NOT naming it the same though).

> * additional definition is needed, the code gets less readable
> * it is bit fragile:
>    - it is not immediatelly clear the enum represents bool value
>    - one can too easily change enum value like:
>     enum { DoNotShow = 1, DoShow };

The only reason that is a problem is because enum to int during
standard conversion lets this fall through.

> If one could mix both of approaches and use something
> as "named bool":
>
> void foo(bool enum { DoNotShow, DoShow} show)
> {
>     if (show) ...
> }
>
> .
> foo(DoNotShow);

Your example looks like it allows implicit conversions from enum to
bool but not the other way around. This is almost exactly how regular
enums work, except in your example I'm guessing bool enum {
DoNotShow=true, DoShow=true } is valid and the compiler wont detect
that error either.

Try this one (you can convert it to a macro to make this easier to
create once and for all):

struct NamedBool {
 typedef void (NamedBool::*Impl)();
 explicit NamedBool(Impl v) : v_(v) {}
 operator Impl() const { return v_; }
 void dummy_() {}
private:
 Impl v_;
};

const NamedBool DoNotShow = NamedBool(0);
const NamedBool DoShow = NamedBool(&NamedBool::dummy_);

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Greg" <greghe@pacbell.net>
Date: Sat, 11 Jun 2005 01:18:07 CST
Raw View

"Pavel Vozenilek" wrote:
> It is recommended to use named enum values
> instead of bool parameters in functions:
>
> // rather discouraged
> void foo(bool show);
> .
> foo(false);   // what the false means here?
>
>
> // encouraged
> enum { DoNotShow, DoShow } show_t;
> void foo(show_t show);
> .
> foo(DoNotShow);
>
>
> Disadvantages are:
> * the enum is visible in the whole class or namespace
> * additional definition is needed, the code gets less readable
> * it is bit fragile:
>    - it is not immediatelly clear the enum represents bool value
>    - one can too easily change enum value like:
>     enum { DoNotShow = 1, DoShow };
>
>
>
> If one could mix both of approaches and use something
> as "named bool":
>
> void foo(bool enum { DoNotShow, DoShow} show)
> {
>     if (show) ...
> }
>
> .
> foo(DoNotShow);
>
> then these symbolic values could be local to function,
> compiler would be able to ensure there are exactly
> two symbols and that their values are 0/1.
> Bool enum would be convertible to bool and vice versa.
>
>
> After implementing chain of functions passing
> bool emulating enums across multiple classes
> I wish something like that existed.
>
> /Pavel
>
>

This disadvantages cited are not really disadvantages. Certainly the
names of the enumberated types are visible for the scope of the class
or namespace; but the conclusion to draw from that fact would be that
classes and namespaces should be kept to reasonable size. Large classes
or namespaces should either be further divided into inner namespaces or
broken apart into separate namespaces or classes as appropriate. As
long as the enumerated types are not global, it is possible to limit
their scope to a reasonable extent.

The enums make the code neither more fragile nor less readable. In fact
the primary reason for using the enum is readability: enumerated types
offer a means of naming the parameters in a function call, rather than
simply providing their values. The role of arguments such as "true" or
"5" may not immediately clear, whereas "Show" or "FiveSecondDelay" may
be much easier to interpret.

The fact that the enum may be replacing a bool parameter in a
particular fnction is irrelevant; and in fact, an enum could just as
easily represent three or more distinct values to a function:
DoNotShow, Show, ShowOnlyIfParentIsVisible. The function declaration
merely has to document the enumerated type that it accepts; the actual
values of the enumerated types and their range are merely
implementation details.

Greg

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: yecril@bluebottle.com ("Krzysztof elechowski")
Date: Sat, 11 Jun 2005 22:02:12 GMT
Raw View
> If one could mix both of approaches and use something
> as "named bool":
>
> void foo(bool enum { DoNotShow, DoShow} show)
> {
>    if (show) ...
> }
>
> .
> foo(DoNotShow);
>

Comparing an enumerated value to an integer literal (0 in this case) is
asking for problems.  You should compare enumerated values to enumeration
literals only, as in

if(MemError() == noErr)

Chris


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "thoth39" <pedro.lamarao@gmail.com>
Date: Mon, 13 Jun 2005 00:09:06 CST
Raw View
> It is recommended to use named enum values
> instead of bool parameters in functions:

> // rather discouraged
> void foo(bool show);

> foo(false);   // what the false means here?

Well, the lack of meaning is not a consequence of using bool, but of
choosing the name "foo":

void show (bool);

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]