#C++ Coding Challenge: Enum Type Size
#🎯 Challenge Overview
Difficulty: Medium
Time: 15-20 minutes
Topics: C++ Fundamentals, Memory Management, Enum Types
Interview Companies: Google, Microsoft, Amazon, Meta
#📋 Problem Statement
#include <iostream>
#include <cstdint>
enum Color {
RED = 0,
GREEN,
BLUE
};
enum Size : uint64_t {
SMALL = 0,
MEDIUM,
LARGE
};
enum Status : char {
INACTIVE = 'I',
ACTIVE = 'A',
PENDING = 'P'
};
int main() {
std::cout << "Size of Color enum: " << sizeof(Color) << " bytes" << std::endl;
std::cout << "Size of Size enum: " << sizeof(Size) << " bytes" << std::endl;
std::cout << "Size of Status enum: " << sizeof(Status) << " bytes" << std::endl;
Color c = RED;
Size s = MEDIUM;
Status st = ACTIVE;
std::cout << "Size of Color variable: " << sizeof(c) << " bytes" << std::endl;
std::cout << "Size of Size variable: " << sizeof(s) << " bytes" << std::endl;
std::cout << "Size of Status variable: " << sizeof(st) << " bytes" << std::endl;
return 0;
}
#🤔 Your Tasks
#Task 1: Predict the Output
#Task 2: Explain the Reasoning
#Task 3: Follow-up Questions
- What determines the size of an unscoped enum?
- How does explicitly specifying the underlying type affect the enum size?
- What are the advantages of scoped enums (
enum class)? - How would the size change if we used
enum classinstead?
#💡 Solution
Click to reveal the solution
#Expected Output
Size of Color enum: 4 bytes
Size of Size enum: 8 bytes
Size of Status enum: 1 bytes
Size of Color variable: 4 bytes
Size of Size variable: 8 bytes
Size of Status variable: 1 bytes
#Explanation
-
Color enum (4 bytes):
- No explicit underlying type specified
- Compiler chooses the smallest integral type that can represent all values (0, 1, 2)
- On most systems, this defaults to
int(4 bytes)
-
Size enum (8 bytes):
- Explicitly specified underlying type:
uint64_t - Size is determined by the underlying type (8 bytes)
- Explicitly specified underlying type:
-
Status enum (1 byte):
- Explicitly specified underlying type:
char - Size is determined by the underlying type (1 byte)
- Explicitly specified underlying type:
#Key Concepts
- Unscoped enums: Size determined by the smallest integral type that can hold all values
- Explicitly typed enums: Size determined by the specified underlying type
- Variable size: Same as the enum type size
#🚀 Advanced Challenge
enum SmallRange : char {
MIN_VAL = -128,
MAX_VAL = 127
};
enum LargeRange : char {
MIN_VAL_2 = -129, // This will cause a compilation error!
MAX_VAL_2 = 128
};
Question: Why does the second enum cause a compilation error?
Advanced Solution
The second enum causes a compilation error because the values -129 and 128 are outside the range of char (which is typically -128 to 127). The underlying type must be able to represent all enum values.
#🎯 Interview Tips
- Always consider the underlying type - it's the key to determining enum size
- Know the defaults - unscoped enums typically use
intas the underlying type - Understand the range - the underlying type must be able to represent all enum values
- Be aware of platform differences -
intsize can vary between systems
#🔍 Real-World Applications
- Memory optimization: Choose appropriate underlying types for enum-heavy data structures
- Network protocols: Fixed-size enums for consistent serialization
- Embedded systems: Minimize memory usage with carefully sized enums
- API design: Explicit underlying types for ABI stability
#📚 Further Reading
- C++ Reference: Enumeration Types
- Effective Modern C++ - Item 10: Prefer scoped enums
- C++ Core Guidelines - Enum recommendations
#🏆 Bonus: Scoped Enums Challenge
What would happen if we changed the code to use enum class instead? Try this:
enum class Color : int {
RED = 0,
GREEN,
BLUE
};
enum class Size : uint64_t {
SMALL = 0,
MEDIUM,
LARGE
};
int main() {
std::cout << "Size of Color enum class: " << sizeof(Color) << " bytes" << std::endl;
std::cout << "Size of Size enum class: " << sizeof(Size) << " bytes" << std::endl;
// Note: This would require explicit casting
// auto c = static_cast<int>(Color::RED);
return 0;
}
Answer: The size would be the same! The main difference is type safety and scoping, not memory usage.
