3

I'm confused with how exactly the enum-type variable and int-type variable works different in C.

I heard there could be a casting error between enum type and integer type in C++, but C doesn't.

Then if there's no difference between integer variable and enum type variable in C, can I just declare enum names and use them without declaring any that enum type variables, for example,

 ...

 enum { WIN, LOSE, DRAW };

 int main() {

     int result;

     result = play_game(...);

     if (result == WIN) { ... }
     else if (result == LOSE) { ... }
     ...

 }

 int play_game(...) {
     ...
     if (...)       return WIN;
     else if (...)  return LOSE;
     else           return DRAW;
     ...
 }

like above. (just for enhancing readability instead of using meaningless numbers; 0, 1, 2, 10, -1, etc.)

Actually, I could not understand what is the meaning of declaring specific enum type variable, like below.

 enum GameResult { WIN, LOSE, DRAW } result;

Is this also related with the code readability? I mean, there any difference between declaring result as int and as enum type variable?

studio-luke
  • 128
  • 8
  • Does this answer your question? [How to define an enumerated type (enum) in C?](https://stackoverflow.com/questions/1102542/how-to-define-an-enumerated-type-enum-in-c) – Hitokiri May 26 '20 at 08:09
  • Does this answer your question? [Why use enum when #define is just as efficient?](https://stackoverflow.com/questions/5243269/why-use-enum-when-define-is-just-as-efficient) – Tony Tannous May 26 '20 at 08:12
  • 1
    enum is a container for a group of constants, it automatically assigns the next +1 value to each constant in the enum, in your example you have not given a name to the enum which acts like a namespace and groups the constants under the assigned name. The major benefits of using enums is that valid values can be checked for. – SPlatten May 26 '20 at 08:12
  • 2
    Declaring a type name for an enum allows you to define function parameters and variables of that type, that *should* only take one of the values defined in the enum. You can certainly use unnamed enum values in your code, but then if you have several different unnamed enums you cannot define variables or function parameters with the enum types. – DNT May 26 '20 at 08:13

3 Answers3

4

Yes, enums are basically int replacement. However, there are some best practice concerns with the code you have posted. The question is borderline subjective, although it is widely recognized as good practice to avoid "magic numbers" in C programming.

That is, you shouldn't write a function that returns an int with either value 0, 1 or 2. That would be a rather cryptic interface. But replacing those "magic numbers" with an enum without changing the return type is sloppy. It should not return int, but instead instead you should have used a typedef like:

typedef enum { WIN, LOSE, DRAW } game_result_t;
...
game_result_t play_game(...)

This gives you a special type only used for this specific purpose. It improves readability and (arguably) adds a tiny bit of type safety.

Better yet, prefix the enum values, the function, everything in the same way, so that the reader can tell which items that belong together:

// game.h

typedef enum { GAME_WIN, GAME_LOSE, GAME_DRAW } game_result_t;
...
game_result_t game_play (...)

Now everything in game.h is prefixed game_, which makes it easy to find out where a certain constant or function came from, without having to dig/search through the code.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Thanks for kind explanation. As you've referred to '_a tiny bit of type safety_', is there any security warning if a function with return type `game_result_t` returns an integer constant(like `1`, `2`)? Or is there any further techniques one can prevent unexpected type conversion? – studio-luke May 26 '20 at 09:21
  • 2
    @studio-luke It is up to the compiler and/or static analyser tool to show such type compatibility messages - nothing in the standard mandates it. As far as the C standard is concerned, integer types of different size and signedness can be mixed pretty wildly at least in theory. There are so-called "safe subsets" of the language though, for example MISRA-C, which has stricter rules for enum type safety, and where using a typedef might make it easier to make the code compliant. – Lundin May 26 '20 at 09:41
3

Yes, identifiers declared in an enumeration may be used as ordinary int constants, per C 2018 6.4.4.3 2: “An identifier declared as an enumeration constant has type int” and 6.7.2.2 3: “The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted.”

I mean, there any difference between declaring result as int and as enum type variable?

Although the enumeration constants have type int, an enumeration object (variable) may have some other integer type. Which it has is implementation-defined, per 6.7.2.2 4.

Together, these imply int values may be assigned to enumeration objects and therefore impedes strong typing when dealing with enumerations, although a compiler can try to do some checking and provide warnings.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
0

Yes enums are used for readability quite often. By default in the enum the first value is 0. And they are indeed like const arrays.

 enum GameResult { WIN, LOSE, DRAW } result;

I don't recommend using that since it is unclear if the result is 8 bit,16 bit or some other value and when it will result an overflow.

spstrademark
  • 445
  • 2
  • 5
  • 22
  • agree with your point of avoiding using the type (as a function parameter especially) since the size is not known – M.M May 26 '20 at 09:43