Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions 01_low_level/07_enums/01_enums_core/enums_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@
// - An enum is a distinct type, but it implicitly converts to int (unscoped enum).
// - Underlying type for unscoped enums is implementation-defined (usually int).
// - Enumerators are integral constant expressions.
// - You can cast any integer to an enum type; the resulting value may not correspond
// to any enumerator. That is not automatically UB just by storing it, but using it
// as if it were a valid enumerator is a logic bug (and may cause undefined behavior
// if you rely on invariants that assume only listed enumerators occur).
// - A non-fixed enum has a restricted value range. Casting an out-of-range
// integer to it has undefined behavior (CWG 1766). An in-range but unnamed
// value is possible; fixed-underlying enums can hold every underlying value.
// - Size of an unscoped enum is implementation-defined (but at least enough to represent values).
//
// Evolution:
Expand Down Expand Up @@ -61,14 +60,15 @@ static void casting_outside_enumerators()
PlainSmall ok = static_cast<PlainSmall>(0);
assert(ok == ps0);

// This produces a value of type PlainSmall that is not equal to any named enumerator.
PlainSmall weird = static_cast<PlainSmall>(20);
// A non-fixed enum with values 1, 2, 4 has a range that includes 3.
// The cast is in range and creates an unnamed, well-defined enum value.
enum Flags { read = 1, write = 2, execute = 4 };
Flags combined = static_cast<Flags>(3);
assert(static_cast<int>(combined) == 3);

// IMPORTANT:
// - It's not "automatically UB" just to have this value.
// - But any code that assumes only ps0/ps1 exist is now broken.
// - In practice: validate when converting from external input.
(void)weird;
// static_cast<PlainSmall>(20) would be undefined behavior: 20 is
// outside PlainSmall's language-defined value range.
// Validate external integers before converting to a non-fixed enum.
}

// Demonstrate why "enums are not just ints" (types differ even if representation matches).
Expand Down
14 changes: 7 additions & 7 deletions 01_low_level/07_enums/02_enums_scoped/enums_scoped.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
// - Underlying type can be specified: enum class E : std::uint8_t { ... }
// - Scoped enums have a fixed underlying type if specified; otherwise still integral but chosen by compiler.
// - Forward declaration:
// * scoped enums can always be forward-declared (with or without underlying type)
// but to be a complete type, it must be defined.
// * an opaque scoped enum declaration is already a complete type because
// its underlying type is fixed (int by default). Enumerator names still
// require the later definition.
// * unscoped enums can only be forward-declared if you specify the underlying type.
//
// Evolution notes:
Expand All @@ -25,7 +26,7 @@
enum class TrafficLight : std::uint8_t { Green = 1, Yellow = 2, Red = 3 };

// Forward decl scoped enum: OK
enum class ErrorCode; // incomplete type until definition
enum class ErrorCode; // complete opaque enum type; enumerators not yet known

// Forward decl unscoped enum: requires underlying type (C++11+)
enum LegacyStatus : unsigned int;
Expand Down Expand Up @@ -87,12 +88,11 @@ static void underlying_type_facts()

static void forward_decl_rules()
{
// You can declare pointers/references to incomplete enum types:
// An opaque enum declaration fixes the underlying type and makes
// the type complete already; only its enumerators remain unknown.
ErrorCode* p = nullptr;
static_assert(sizeof(ErrorCode) == sizeof(int));
(void)p;

// But you cannot sizeof an incomplete type:
// sizeof(ErrorCode); // ERROR if only forward-declared
}

int main()
Expand Down
Loading
Loading