[LC++]enum, #define, const, static const, or member const???

Mark Phillips mark at austrics.com.au
Tue Apr 9 11:06:04 UTC 2002


Carlo Wood wrote:

> On Mon, Apr 08, 2002 at 05:59:07PM +0930, Mark Phillips wrote:
> 
>>Why is this bad?  If all the data handling routines use the
>>enums appropriately, the data will all shift perfectly without
>>error.
>>
> 
> Because it is less maintainable.  How do you know that another
> programmer who added code 5 months ago in the 4 megabyte big
> source subtree artificial-intelligence/ didn't use your enum
> in a slighty different way?  You'd have to check the correct
> usage in ALL of the 150 megabytes source code...


I suppose it depends on how much you trust the programmers in
your project.  The way I like to code is to "make a contract"
with the users of any library I provide.  Ie something along
the lines of: "If you, the user, use my library in the proper
way then I, the library writer, will ensure things work
the way they are supposed to."

So if I set up an enum type and specify that it is only to be
used in such-and-such a way, then users of this enum should
abide by this.  If they don't, it is at their own risk.

I agree that if you work in an environment where

1. you can't trust the other programmers to do the right thing; and

2. you have some responsibility for the integrity of the whole
    project

then my system of "contract" breaks down and a stronger enforcement
model may be required.


> The point that I am trying to make is that you shouldn't
> use enums when you need to assign values to them in a way
> that insertion of new values at any point doesn't work anymore.


Good advice.  Well except to say that you might want to make
a contract with the user saying: "if this enum does change, it will
only change via insertion at the end points; numbering may change
but relative positions wont".  That way the user could rely on
some of the structure not changing.


> Your examples worked and were correct, but you used the edges
> of the subgroups.  This would break:
> 
> enum foo {
>   green = 0,
>   yellow = 1,
>   blue = 2,
>   white = 3
> };
> 
> // USE the integer values:
> 
> if (color == 2) // we know it is blue


This is bad unless you have a "contract" saying the integral values of
colours will not change.  (It is probably bad anyway because having
(color == blue) is more readable.)


> if (color1 - color2 == 1) // Hey, that seemed the best way to detect that 

>                           // color1 == green && color2 == blue


There's a bug here for a start:-)... but back to the point... if
you have a contract that relative values won't change then this
kind of thing is okay.


> char colorNames[] = { "green", "yellow", "blue", "white" };


Surely this would be okay as long as you updated colorNames at the
same time as you updated foo?

> if (color & 1) { 'a light color' }	// Overloading the least-significant bit


Not a good idea. :-)

Cheers,

Mark.







More information about the tuxCPProgramming mailing list