Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


C++0x Forward Enum Declarations Cut Down Compilation Time and Dependencies : Page 2

A new C++0x feature called forward enum declarations allows you to declare an enumeration without providing its enumerators list. Learn how using it can avert long compilation times and ODR violations.




Application Security Testing: An Integral Part of DevOps

The Repeated Enumerators List Problem

In many C++ projects, enum types that contain hundreds of enumerators are quite common. Often, these enum types are machine-generated and updated frequently. Examples of such huge enum types include a list of international airports, a list of locales supported by the application, and so on.

The problem is that whenever you update such an enum, every translation unit that references it must be compiled as well—even if the code that references the enum hasn't changed. Consider the list of airports as an example:

//file: airports.h #ifndef AIRPORTS_H #define AIRPORTS_H enum class Airports: int { CPH, CDG, //..many more entries LAX, LHR, //..many more entries }; #endif

Seemingly, the following piece of code doesn't depend on the list of Airports' enumerators, as adding a new enumerator, changing an existing enumerator, or deleting one doesn't affect Airports' enum base (which is int):

#include "airports.h" std::istream& operator>>(std::istream& is, Airports& ap); std::string get_ap_name(Airports ap); Airports ap; std::cin >> ap; std::cout << get_ap_name(ap);

Theoretically, the compiler can process this code without needing a complete definition of Airports, but that isn't the case. C++03 requires the presence of the entire list of enumerators to determine the underlying type of Airports. This leads to a longer compilation time and increases the risk of ODR(One Definition Rule) violations.

Scoped Enums and Enum Bases

Before diving deeper into forward declaration of enum types, you need to understand two key concepts: scoped enum types and enum bases. A scoped enum is one that is declared with the class keyword, as opposed to a traditional enum, which is unscoped.

Among other things, scoped and unscoped enums differ with respect to enumerator qualification:

enum class A {x,y}; //scoped enum B {t,u}; //unscoped A a1=A::x; //OK, qualified enumerator A a2=y; //error, y is unqualified B b=t; //OK, unscoped. Enumerator isn't qualified

As previously stated, an enum base is the underlying integral type of the enumeration. Recall that the compiler represents every enum type as an unspecified integral type that is large enough to hold every enumerator value. For scoped enums, the default base type is int. You can override it by specifying a different enum base explicitly, like this:

enum class A {x,y}; //scoped, base is int enum class Q: char {x,y}; //scoped, base is char

In C++0x, an unscoped enum may also include an explicit enum base. Notice, however, that unlike scoped enums, an unscoped enum doesn't have a default enum base:

enum C: int {x,y}; //unscoped, enum base is int enum D {x,y}; //unscoped, no enum base

This presents a problem: the compiler must know what the enum base is to compile any piece of code that refers to that enum. Now you are ready to learn how forward declarations solve this problem.

Comment and Contribute






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



Thanks for your registration, follow us on our social networks to keep up-to-date