tags:

views:

593

answers:

5
+2  Q: 

C enums question

I'm not sure what is the proper syntax for using C enums. I have the following code:

enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;

But this does not compile, with the following error:

error: conflicting types for ‘strategy’
error: previous declaration of ‘strategy’ was here

What am I doing wrong?

+13  A: 

You need to use typedef like this:

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy my_strategy = IMMEDIATE;

Having a naming convention to distinguish between types and variables is a good idea:

typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_t;
strategy_t my_strategy = IMMEDIATE;
RichieHindle
+1 typedef [15char]
Daniel
+10  A: 

When you say

enum {RANDOM, IMMEDIATE, SEARCH} strategy;

you create a single instance variable, called 'strategy' of a nameless enum. This is not a very useful thing to do - you need a typedef:

typedef enum {RANDOM, IMMEDIATE, SEARCH} StrategyType; 
StrategyType strategy = IMMEDIATE;
anon
Why is this not useful? If I don't care about the name of the type, why should I give it one? The only thing intended here was to name the variable, so it's possible to assign new values to it.
MSalters
I said it was not VERY useful, and I don't believe it is. Certainly, I don't use this pattern in my own code. YMMV.
anon
+1  A: 

It's worth mentioning that in C++ you can use "enum" to define a new type without needing a typedef statement.

enum Strategy {RANDOM, IMMEDIATE, SEARCH};
...
Strategy myStrategy = IMMEDIATE;

I find this approach a lot more friendly.

[edit - clarified C++ status - I had this in originally, then removed it!]

Roddy
Yes, you should never use typedef with enums (or structs, unions etc.) in C++.
anon
This question is for C, not for C++. In C, the above code is invalid - you either have to use `typedef`, or specify `enum` in variable declaration as well: enum Strategy {RANDOM, IMMEDIATE, SEARCH}; ... enum Strategy myStrategy = IMMEDIATE;
Pavel Minaev
@pavel - my bad. I had "in C++" in originally, then did some research which seemed to contradict that.
Roddy
@Pavel I think it should be a separate answer describing the benefits of using `enum Strategy`. I did that, see below.
Johannes Schaub - litb
+2  A: 

As written, there's nothing wrong with your code. Are you sure you haven't done something like

int strategy;
...
enum {RANDOM, IMMEDIATE, SEARCH} strategy;

What lines do the error messages point to? When it says "previous declaration of 'strategy' was here", what's "here" and what does it show?

John Bode
He probably did `strategy = IMMEDIATE;` at file-scope. An assignment can't happen at file-scope outside all functions. So the compiler tried to do the best out of the error and assumed he meant `int strategy = IMMEDIATE;`, at which point the conflict happened.
Johannes Schaub - litb
Ah, good point. Didn't think about that.
John Bode
+3  A: 

It's worth pointing out that you don't need a typedef. You can just do it like the following

enum strategy { RANDOM, IMMEDIATE, SEARCH };
enum strategy my_strategy = IMMEDIATE;

It's a style question whether you prefer typedef. Without it, if you want to refer to the enumeration type, you need to use enum strategy. With it, you can just say strategy.

Both ways have their pro and cons. The one is more wordy, but keeps type identifiers into the tag-namespace where they won't conflict with ordinary identifiers (think of struct stat and the stat function: these don't conflict either), and where you immediately see that it's a type. The other is shorter, but brings type identifiers into the ordinary namespace.

Johannes Schaub - litb