ProgrammingEmbedded Developer

Tell us in detail about the rules for describing and using enumerations (enum) in C. What are their advantages and weaknesses compared to #define? How can type errors be avoided?

Pass interviews with Hintsage AI assistant

Answer

Enumerations (enum) in the C language are a way to define a set of named integer constants. The typical syntax:

enum Color { RED, GREEN, BLUE };

By default, the first value is assigned 0, and each subsequent value is the previous one + 1.

Advantages of enumerations:

  • Increases readability: meaningful names are used instead of magic numbers.
  • Simplifies grouping of related constants.
  • Allows the compiler to perform additional type checks (provided enum is used as a standalone type).

Weaknesses:

  • enum in the C standard has type int (before C99), so there is no strict type safety.
  • Implicit conversion between enum and int (no range control).
  • Cannot explicitly set the type in C90/C99 (only starting from C11: enum MyType : unsigned char — but this is an extension).

Example:

enum State { INIT = -1, RUNNING = 0, PAUSED = 1, STOPPED = 2 }; enum State current = RUNNING;

Trick Question

Question: Can values of different enumerations be safely compared to each other?

Answer: Although technically the values of enum are int, comparing variables of different enumerations is undesirable. This leads to a loss of semantics and can confuse the reader, as well as complicate future code maintenance. It is better to explicitly convert the type or regroup the enumerations logically.

Example of a mistake:

enum Fruit { APPLE, BANANA }; enum Animal { CAT, DOG }; if ((enum Fruit)BANANA == (enum Animal)CAT) { ... } // Logical error

Examples of real mistakes due to ignorance of the intricacies of the topic


History

In the interprocessor message protocol, messages were limited to #define with non-unique names, leading to value collisions when extending the protocol. Switching to enum simplified the control of used identifiers and made debugging easier.


History

In a large library, state handling was performed using hard-coded int values. During refactoring, they forgot to synchronize all defines to the new values. Using enum helped prevent this, but one module continued to use outdated defines, causing hard-to-detect errors.


History

In a robotic node control system, the engineer did not explicitly set values for the first element of the enum (only the second and third were used). The program worked incorrectly because the first element defaulted to 0, which conflicted with the logic of the exchange protocol expecting a different value.