Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Safeguard Your enums: Make Them Strongly-Typed-2 : Page 2


advertisement
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 type s=2;//error, can't convert int to Set s=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 unknown b=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 visible enum Rate {Up, Down};//error, Up & Down already defined int 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.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap