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


Error Handling: The Sooner, The Better : Page 3

Dealing with errors means determining anomalous and incorrect settings in your target environment, and it should be done as early as possible. Find out how.


Code Simplification
You can simplify the upper #if-#endifblock by collapsing the two conditions into a single statement:

#if defined (__STDC_UTF_32__) || defined (__STDC_UTF_16__)
 #error "Unicode support required for this application!"

If you're not fond of empty # directives, you can rewrite the conditional expression further as:

#if !defined (__STDC_UTF_32__) && !defined (__STDC_UTF_16__)
  #error "Unicode support required for this application!"

The point here is to show that the preprocessor recognizes the logical operators &&, !=, <, etc. so you can combine them in complex conditional expressions.

What #if
There are some differences between the if-statement of C and C++ and the #if preprocessor directive. Unlike the C++ if-statement, #if takes only a restricted subset of integral constant expressions. More specifically, sizeof expressions cannot be used in an #if directive. The reason for this is that sizeof requires the invocation of the compiler, whereas #ifis evaluated conceptually before compilation.

This restriction raises a problem. Suppose you want to ensure that your app is compiled only with 64-bit addressing mode. Seemingly, one could use the following expression to ensure that the size of a pointer is larger than 32 bits:

#if (sizeof (void*)<= sizeof(int32_t))
 #error "this app requires 64-bit addressing"

However, as previously explained, sizeof expressions cannot be used in this context. Therefore, the best way to detect such configuration problems during the preprocessing stage is to #define a macro symbol for every condition and then check whether that macro has been #defined. In the case of 64-bit addressing, there isn't a standard macro yet; each platform uses its own macro. For example, Windows Visual Studio 2005 automatically #defines the macro _Wp64when the project is compiled as a 64-bit Windows application. Therefore, you can use the following test to enforce 64-bit addressing mode for Windows apps:

#if !defined (_Wp64)
 #error "This application requires 64-bit addressing"

The Importance of Early Detection
Many applications use the assert() macro (or worse yet, exceptions) to enforce constraints that can be checked much earlier. Using the #if and #errordirectives for the early detection of incorrect hardware configuration and compiler settings is a better strategy as it ensures that no executable is produced when it shouldn't. This way not only are you saving precious time and resources on building, distributing, and loading an executable that shouldn't have been produced in the first place, you're also protecting your clients from data corruption and security loopholes that a might arise due to a crash.

Danny Kalev is a certified system analyst and software engineer specializing in C++. He was a member of the C++ standards committee between 1997 and 2000 and has since been involved informally in the C++0x standardization process. He is the author of "The ANSI/ISO Professional C++ Programmer's Handbook" and "The Informit C++ Reference Guide: Techniques, Insight, and Practical Advice on C++."
Email AuthorEmail Author
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date