|
Replacing Bool Arguments With Enums
Submitted by |
I try to be careful of using bools or ( BOOLS ) for arguments to
functions, because it's common for argument lists to have several bools in a
row, which makes it easy to get their order mixed up, thus creating a
hard-to-find bug.
Another potential bug is created when one passes in an unsigned int that
the compiler silently converts to a bool, or vice-versa, causing numerous
headaches when trying to track this problem down.
I like to use enums instead to replace bool arguments in cases where there
is more than one bool in the argument list. Using enums prevents the
compiler from employing silent conversions, thus forcing the compiler to
verify the parameter order and types for you.
Using bools, you might see a bit of code that does this :
Object-Draw( false, true ); |
First of all, it's not clear what the parameters mean to someone glancing at
the code. One would have to look at the header file or implementation to
deduce the parameter meanings, at even then it would be easy to miss the
fact that you mistakenly switched the order of the arguments. You could put
a comment before the ->Draw call, but there is a chance it won't be updated
properly to reflect subsequent changes to the ->Draw call.
I prefer to use enums like so :
Object-Draw( Object::DontClip, Object::UseWireFrame ); |
Where Object is defined like so :
class Object
{
enum Clip
{
Clip = 1,
DontClip = 2
};
enum DrawStyle
{
UseSolid = 3,
UseWireFrame = 4,
UsePoints = 5
};
void Draw( const Clip& aClip, const DrawStyle& aDrawStyle );
}; |
Two things to note is that the enums are defined within the class to prevent
name conflicts and to associate the options with the class that needs them,
and that one should use meaningful enum names to get the most mileage out of
this technique. I also use disjoint integer ranges to create further
distinction between enum types.
Enums are also handy for return codes. They are better than #defines due to
their limited scope, and the compiler won't let you confuse one enum type
with another.
I now use enums where I used to use const ints within a class because enums
can be defined to have a value within a header file, which is very handy for
templates.
One thing to note is that enums still have an implicit conversion to an int,
although in practice I find this more useful than dangerous, but if you are
concerned about this, make your enum int values something like 0xdddddd0 to
make it easier to spot implicit conversions. Additionally, you could hide
the enum type inside of a dummy type to prevent implicit conversion to int.
E-mail me if you are interested.
|
The zip file viewer built into the Developer Toolbox made use
of the zlib library, as well as the zlibdll source additions.
|