When programming in C, is it better practice to use #define statements or enums for states in a state machine?
Since the states are related elements I think is better to have an enum defining them.
I prefer enum. They are more compact and are 'safer'. You can also imply order in an enum, which might be helpful in a state machine. #defines should be avoided if possible, since they will overwrite all occurrences in source, which can lead to some unintended actions which are difficult to debug.
#define
directives can have lots of unintended consequences and don't follow common scoping rules. Use enums when you have related data.
More information: http://www.embedded.com/columns/programmingpointers/9900402?_requestid=341945 [C++ material, but still marginally relevant]
If enum
is supported by your compiler, then that would be preferred. Failing that, by all means, use #define
. All C++ compilers and modern C compilers should support enum
, but older compilers (particularly ones targeting embedded platforms) may not support enum
.
If you must use #define
make sure to define your constants with parentheses, to avoid preprocessor errors:
#define RED_STATE (1)
#define YELLOW_STATE (2)
#define GREEN_STATE (3)
There's no definitive answer. enum
offers you scoping and automatic value assignment, but does not give any control over the constant type (always signed int
). #define
ignores scoping, but allows you to use better typing facilities: lets you choose the constant type (either by using suffixes or by including an explicit cast into the definition).
So, choose for yourself what is more important to you. For a state machine, enum
might be a better choice, unless you have a good reason to control the type.
enum
is great when you have exclusive options, but you can't use them to define bitfield flags, like this:
#define SQ_DEFAULT 0x0
#define SQ_WITH_RED 0x1
#define SQ_WITH_BLUE 0x2
void paint_square(int flags);
Then you can paint red-blue square with:
paint_square(SQ_WITH_RED | SQ_WITH_BLUE);
...which you can't with enum
.
Technically it doesn't matter. The compiler will most likely even create identical machine code for either case, but an enumeration has two advantages:
Using the right compiler+debugger combination, the debugger will print enumeration variables by their enumeration name and not by their number. So "StateBlahBlup" reads much nicer than "41", doesn't it?
You don't have explicitly give every state a number, the compiler does the numbering for you. Let's assume you have already 20 states and you want to add a new state in the middle, in case of defines, you have to do all renumbering on your own. In case of enumeration, you can just add the state and the compiler will renumber all states below this new state for you.
You can use whatever you want and like.
Still as everyone is saying I would also like add up me as voting for Enums.
Enums should always be preferred if you are using related data as in case of a State Machine, you can define order in enums also that will help in implementing the State Machine.
Further enums will keep your program safe as all enums will be of its type only so they will avoid any possible confusions too.
#define should not be used in case of a state machine or related data. Anyway thats my suggestion, but there is no hard and fast rule.
Also I would like to add up one more point that enums will add more readability and understandability to your code if used in future or or if read by someone else. It is an important point when you are having a very large program and there are a lot of #defines in the program other than you are using for your State Machine.