What are the drawbacks of using enum ?

Share the Article

Although enum is a very handy way of working with integers, because it attaches human-readable (enumerated) names to list of numbers. The enums therefore, greatly improve the readability of code.

Example:

#include <iostream> using namespace std; int main() { enum validcolors { red, green, yellow }; for (int i=red; i<=yellow; i++) { cout<<"Hello - " << i << endl; } return 0; }

Output

Hello - 0 Hello - 1 Hello - 2

However, there are serious drawbacks with enum variables in standard C++.

First drawback

Drawback is that the enums by its basic nature pollute the scope where it is defined. This means that apart from being the enumerated name, the user will no longer be able to use this name any longer in same scope. Example, any of the variable in same scope cannot use this name.

enum validcolors { red, green, yellow }; int red = 8; // this line is problematic

Output

Result is Compiler Error: error: ‘int red’ redeclared as different kind of symbol

Please note, if the enum definition and variable definition would have been in different scope, then compiler will be ok.

Main Funda : Enum pollutes the scope

Second drawback

Another drawback with enums is that although from outside they look like names but in reality they are integers so they implicitly convert to any other data type which is compatible with integers. Like, an enum may get implicitly converted to floating-point types (float, double) or even to a different enum variable whose meaning is completely different.

Compiler sees the following code as absolutely ok !

enum validshapes { circle, rectangle, triangle }; int newcolor = red; newcolor = circle; // This is outrageous

Also, following code is ok too !

if( red < 2.3) { cout << “correct” }

Such coding practices will potentially leave loop-holes and will be prone to misuse.

Main Funda: Enums are just integers and they get converted implicitly like integers

The last drawback

Final drawback is that enums cannot be forward declared. The following code will not work.

enum validcolors; class shape { void draw(validcolors aColor); };

The result is an error:

error: ‘validcolors’ has not been declared

The definition part is so much important for compilers because, they need to assign proper integral types (like, std::uint8_t or std::uint16_t or std::uint32_t) to store an enum, and this can happen only after the complier see the whole definition. Generally, the compiler chooses best possible match to optimize on storage size and speed.

Main Funda: Enums cannot be forward declared because compiler do now the exact size of data type.

How modern C++ has solved this problem

C++11 resolves all the drawbacks of old style enums. Now, the enums have evolved into a new datatype called “scoped enums”. Now, they are no longer just a name of integer value but they are now more like a class.

The (scoped) enum is now similar to a class, therefore enum now follows proper class semantics. This means, the program should access the name with scope resolution operator (just like it does for accessing member of any class) The enum will simply cannot act like integers by default.

Just like, class members who never pollute the scope, in the same way enumerated names will not pollute the scope now.

enum class validcolors { red=1, green, yellow }; validcolors i=validcolors::red;

Scoped enum has to be explicitly cast to specific types to get the desired functionality (even for making it work like integers)


validcolors i=validcolors::red; cout << static_cast<int>(i); // Correct way cout << i ; //Incorrect way

The forward declaration will be completely valid for scoped enum (in C++11) because the enum is more like a class.

Main Funda: Scoped enums has solved the fundamental issues with enums.

Related Topics:

 What are the drawbacks of using enum ?
Which member functions are generated by compiler in class?
How to stop compiler from generating special member functions?
Compiler Generated Destructor is always non-virtual
How to make a class object un-copyable?
Why virtual functions should not be called in constructor & destructor ?
Explaining C++ casts
How pointer to class members are different ?
How std::forward( ) works?
What is reference collapsing?
How std::move() function works?
How delete keyword can be used to filter polymorphism
Rule of Three

Share the Article

Leave a Reply

Your email address will not be published. Required fields are marked *