Despite its large number of votes and its highly upvoted answers, the question you reference is based on a completely false premise. It asserts that this code is erroneous in C:
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
In fact, however, that code is perfectly fine in C89, C99, and C2011. It declares variable strategy
to be of an anonymous enumerated type with the given enumeration constants, and it initializes that variable to one of the three values defined for its type. The error messages the OP of that question reported may have been emitted by a non-conforming compiler, or perhaps there was more to the story than that OP presented.
On the other hand, that form of variable declaration is of comparatively little practical use, because no other object can be declared to have the same type as the variable declared there. There are two alternatives for declaring an enumerated type so that it can be used in multiple declarations:
- Declare the type with a tag:
enum strategy_tag {RANDOM, IMMEDIATE, SEARCH} /* ... */ ;
- Use a
typedef
to name the type: typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_type;
How you then refer to the type depends on which form you used. If you declare the type as a tagged enum, then you can use it in declarations by referencing the tag:
enum strategy_tag my_strategy = RANDOM;
. If you declare the type as a typedef
'd name then you use the defined name as the type name
strategy_type my_strategy = IMMEDIATE;
. These are not exclusive; you can both tag an enum
and declare a typedef
for it, in separate statements ...
enum strategy_tag {RANDOM, IMMEDIATE, SEARCH};
typedef enum strategy_tag strategy_type;
... or even in one ...
typedef enum strategy_tag {RANDOM, IMMEDIATE, SEARCH} strategy_type;
. If you use both forms of type declaration then you can use either or both forms of type specifier in variable declarations.
Additionally, be aware that the namespaces for enum tags, type names, and variable names are all separate, so although it might be a bit confusing, you can do this:
typedef enum strategy {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy strategy = RANDOM;
enum strategy strategy2 = strategy;
As for which way is best, the answer is not so clear. If you have an established set of coding conventions that address this question then of course it is best to follow the conventions. If not then you can choose, but be consistent, at least within any given project. I tend to think that typedef
s are overused in general, but using then to name enum
s is one of the uses I think makes sense. If you do that, however, then I suggest not declaring tags for typedef
'd enum
s -- since you're after consistency, explicitly providing a mechanism for inconsistency is counterproductive.