How to define an enumerated type (enum) in C?

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?


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.


Declaring an enum variable is done like this:

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

However, you can use a typedef to shorten the variable declarations, like so:

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_type;
strategy_type my_strategy = IMMEDIATE;

You're trying to declare strategy twice, and that's why you're getting the above error. The following works without any complaints (compiled with gcc -ansi -pedantic -Wall):

#include <stdio.h>

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

int main(int argc, char** argv){
    printf("strategy: %d\n", strategy);

    return 0;
}

If instead of the above, the second line were changed to:

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

From the warnings, you could easily see your mistake:

enums.c:5:1: warning: data definition has no type or storage class [enabled by default]
enums.c:5:1: warning: type defaults to ‘int’ in declaration of ‘strategy’ [-Wimplicit-int]
enums.c:5:1: error: conflicting types for ‘strategy’
enums.c:4:36: note: previous declaration of ‘strategy’ was here

So the compiler took strategy = IMMEDIATE for a declaration of a variable called strategy with default type int, but there was already a previous declaration of a variable with this name.

However, if you placed the assignment in the main() function, it would be a valid code:

#include <stdio.h>

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

int main(int argc, char** argv){
    strategy=SEARCH;
    printf("strategy: %d\n", strategy);

    return 0;
}

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;