Safeguard Your enums: Make Them Strongly-Typed

num types have been a valuable asset in the arsenal of C++ programmers for many years. However, their current specification has some security loopholes that can lead to bugs and portability problems. Recently, the C++ standards committee accepted a new proposal for strongly typed enum types. As with all other C++09 proposals, it may take some time before your compiler supports this feature, but it’s not a moment too soon to learn how to use this feature or how to make your code C++09-ready.


How can you avoid implicit conversions of enumerators to integral types? Or specify the exact underlying type for a certain enum?


Use C++09 strongly-typed enums.

Implicit Conversions
Contemporary enum types (henceforth, I will refer to them as traditional enum types) are only partially type-safe. Indeed, it’s impossible to initialize an enum variable with an enumerator of a different enum type:

enum Set {E1=1, E2};enum Dir{Up, Down};Set s=E1; //OK, same types=2;//error, can't convert int to Sets=Down; //error, can't convert Dir to Set

However, implicit conversions of enum types to integral types are allowed. They can cause unpredictable runtime behavior, as the following example shows:

bool b=s; //dangerous, s's value is unknownb=E2; //undefined behavior

Some compilers will issue warning messages when they encounter such mishaps. However, it isn’t always possible to tell at compile time whether the value of enum variable can fit into a Boolean value. If s equals E1, the initialization of b is valid. If however s equals E2, b will have an indeterminate value.

Size Issues
The inability to specify a predictable and portable size for enum types is another problem, particularly in applications that serialize data or read data from remote databases. Consider the enumeration Set. A C++ compiler is free to store it in a char, or use a larger underlying type for it such as short, int, and long. This means that the sizeof (s) can range between one to four bytes, depending on the specific compiler and compilation flags used. Presently, standard C++ has no mechanism for specifying an underlying type of enum types. If you must have a specific underlying type, the current workaround consists of replacing enum types with plain constants:

const int32 E1=1;const int32 E2=2;

However, this approach is inelegant and dangerous. The programmer must provide an explicit value for each constant, risking the creation of duplicates:

//..long list of constants const int32 E73=1; //oops, same as E1

Traditional enums have one more problem. The scope of their enumerators propagates to their enclosing scope, often causing name conflicts and ambiguity:

enum Dir {Up, Down}; //Up & Down are globally visibleenum Rate {Up, Down};//error, Up & Down already definedint main(){ int Rate=5;//error, Height already defined}

Although Dir and Rate are distinct types, their enumerators are globally visible, causing name conflicts. In contemporary C++, there are two common workarounds to this problem:

  • declaring the enumerators in different namespaces
  • changing the enumerators’ names

The first technique is cumbersome and can still cause name conflicts if a source file has multiple using declarations. The latter is slightly better, but it isn’t always an option for programmers using third-party libraries and compiled binaries. It’s time to see how the new strongly-typed enums solve all these problems elegantly.

enum Classes
Appending the class keyword to an enum declaration creates a strongly typed enum. Unlike a traditional enum, a strongly-typed enum isn’t implicitly converted to integral types:

enum class Set //C++09 strongly-typed enum{  E1,  E2,  E3 = 4,  E4 = 8};  void g(Set s ) { if( s > 10 ) // error, can't convert Set to int Set s2=Set::E1; //OK}

Strongly-typed enums are represented as int by default. However, you can specify a different underlying type using inheritance-like syntax. For example, to specify an underlying type of unsigned short for Set, declare it like this:

enum class Set: unsigned short {  E1,  E2,  E3 = 4,  E4 = 8 };  

Scope
Strongly-typed enumerators’ scope is restricted to their enclosing enumeration. It doesn’t propagate to the enclosing scope. This property reduces the risk of name conflicts and ambiguities to a minimum. To refer to such enumerators from an external scope, use their qualified names:

enum class Set: char {E1, E2};  Set s=E1; //error, E1 isn't recognized in this scopeSet s=Set::E1; //OK, qualified enumerator used

Ease and Safety
Strongly typed enums can coexist with traditional enums. Therefore, legacy code will continue to work as expected even after this feature is added to C++. However, upgrading traditional enums to strongly-typed ones is an easy and welcome step. Simply add the class keyword to the declarations of traditional enum types and recompile. To make your existing enums C++09-ready and facilitate future migration, you can use conditional compilation for the time being:

#ifdef CPP09_STRONGLY_TYPED_ENUMS#define CPP09_ENUM class#else#define CPP09_ENUM #endifenum CPP09_ENUM Color //traditional or strongly-typed{ Red,  Green,  Blue};  
Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

The Latest

6 Web Resources for Coders

6 Online Coding Resources

One of the most rapidly growing job industries today is coding. As more and more of the world moves to a digital format, the demand for skilled coders continues to increase. With a high demand for the skillset, coders tend to be very well compensated for their work. Furthermore, coders

Malware Removal and Protection Software You Should Use in 2023 

The Best Malware Removal Software in 2023

In the modern world, computers are practically a necessity for every home. Computers give us access to vast amounts of information through the internet, as well as provide us with innovative programs and applications like social media, email, and much more. But with these benefits also come the threats of

Why Technology Literacy is So Important for Modern Workers 

Why Technology Literacy is So Important for Modern Workers 

Importance of Having Technology Literacy Today’s world is completely reliant on technological products and advancements. In the current technology-based era, it is crucial to have technology literacy. And these particular instances might be most suitable for the cases of modern workers dealing with modern equipment, especially in the construction sector. 

The Small Business & Data Analytics: What You Need to Know

The Small Business & Data Analytics: What You Need to Know

The objective of any business is to afford its community a product and create extra money for the services provided. Ideally, this always goes as planned, but at times when it doesn’t, having an extra eye on the data analytics of your small business may make a significant difference. Metrics

Break Into Tech Sales in 4 Easy Steps

Break Into Technology Sales in 4 Easy Steps

One of the fastest-growing industries of the 21st century is undoubtedly tech sales. Between innovations like computers, AI, social media, and more, tech is everywhere. And the demand continues to increase. With constant innovations and massive demand, tech sales have become an extremely lucrative industry. As such, there is no