/* cutlery.h */
#define KNIFE (0)
#define FORK (1)
#define SPOON (2)
...all following occurences of the token SPOON will be textually
substituted with the token 2. The danger is that all really does
mean all. Consider this fragment:
/* fubar.h */
#include "cutlery.h"
#include "fishing.h"
The danger is that fishing.h may contain (now or at some later date) this:
#define SPOON (1)and the fragment will 'expand' to:
#define SPOON (2) ... #define SPOON (1)If this happens your compiler will probably generate a warning something like this:
Warning YOURSELF 3: Redefinition of 'SPOON' is not identical
but it will not generate an error and the compilation will continue.
There is a better way. Instead of writing:
#define KNIFE (0) #define FORK (1) #define SPOON (2)write, { yourself }, this:
enum cutlery { KNIFE, FORK, SPOON };
This is perfectly legal. SPOON is a fully fledged constant [1].
Now if you write:
enum cutlery { KNIFE, FORK, SPOON };
enum pike_bait { PLUG, SPOON, LURE };
the compiler will issue an error (not a warning) and stop the
compilation [2]. The reason is that enum constants live in a single
global namespace. Duplicates are simply not permitted.
Now that SPOON has changed from a #defined constant to an enum constant it's as well to remember that changes have a way of rippling out, of touching and affecting and interacting with other code. Will this change interact with anything? It might! Remember that uppercase is traditionally reserved for #defines...
#define SPOON (42)
...
enum cutlery { KNIFE, FORK, SPOON };
Ooops. A change from all uppercase is in order.
enum cutlery { knife, fork, spoon };
As a final added bonus you may now find your debugger is a little
more helpful, displaying the token spoon where previously it
displayed 2.
That's all for now.
Cheers
Jon Jagger
jon@jaggersoft.com