Lesson content
Read, practise, then check your understanding
An enumeration defines a set of named integer constants. It improves readability for states, modes, result kinds, and other finite choices.
enum ConnectionState {
CONNECTION_DISCONNECTED,
CONNECTION_CONNECTING,
CONNECTION_CONNECTED,
CONNECTION_FAILED
};
Without explicit values, the first enumerator is zero and each following value increases by one. Values may be assigned and later entries continue from them.
enum HttpStatus {
HTTP_OK = 200,
HTTP_NOT_FOUND = 404,
HTTP_SERVER_ERROR = 500
};
Use enums in control flow
const char *state_name(enum ConnectionState state) {
switch (state) {
case CONNECTION_DISCONNECTED: return "disconnected";
case CONNECTION_CONNECTING: return "connecting";
case CONNECTION_CONNECTED: return "connected";
case CONNECTION_FAILED: return "failed";
}
return "invalid";
}
Compilers can warn about missing enum cases when a switch omits default. Whether to include a default depends on the contract: it can safely handle invalid input, but can also hide a newly added enumerator from warning-based review.
Enums are not automatic validation
An enum object can receive integer values outside its listed enumerators through conversions or corrupted input. Validate values that cross trust boundaries.
Enumeration constants are integer constant expressions, useful for compile-time array sizes and case labels. Traditional C does not guarantee a specific storage width for every enum; do not use raw enum representation in a portable file or network format.
Flags are different
Mutually exclusive states suit enums. Combinable options suit unsigned bit masks:
enum Permission {
PERMISSION_READ = 1u << 0,
PERMISSION_WRITE = 1u << 1,
PERMISSION_EXECUTE = 1u << 2
};
The type system does not prevent mixing unrelated enum values, so use distinctive prefixes and narrow interfaces.
Knowledge check
Answer every question correctly to complete this chapter.
0 of 10 checks passed
Your progress is saved on this device.