Problem
You want to define the preprocessor symbol name, assigning it either an unspecified value or the value value.
Solution
The compiler options for defining a macro from the command line are shown in Table 1-16. Instructions for defining a macro from your IDE are given in Table 1-17. To define a macro using Boost.Build, simply add a property of the form name[=value] to your target's requirements, as shown in Table 1-15 and Example 1-12.
Toolset |
Option |
---|---|
All |
-Dname[=value] |
IDE |
Configuration |
---|---|
Visual C++ |
From your project's property pages, go to Configuration Properties images/U2192.jpg border=0> C/C++ images/U2192.jpg border=0> Preprocessor and enter name[=value] under Preprocessor Definitions, using semicolons to separate multiple entries. |
CodeWarrior |
From the Target Settings Window, go to Language Settings images/U2192.jpg border=0> C/C++ Preprocessor and enter: #define name[ = value] in the area labeled Prefix Text. |
C++Builder |
From Project Options, go to Directories/Conditionals and enter name[=value] under Preprocessor Definitions, using semicolons to separate multiple entries. |
Dev-C++ |
From Project Options, select Parameters and enter: -D name[ = value] under C++ Compiler. |
Discussion
Preprocessor symbols are used frequently in C++ source code to allow a single collection of source files to be used with several build configurations or operating systems. For example, suppose you want to write a function that checks whether a file is a directory. Currently, the C++ standard library does not provide the functionality necessary to perform this task; consequently, your function will need to make use of platform specific features. If you want your code to work both on Windows and on Unix, you'll have to make sure that the code that makes use of Windows-specific features is not visible to the compiler when compiling on Unix, and vice versa. The usual way to achieve this is through conditional compilation , as illustrated in Example 1-25.
Example 1-25. Conditional compilation using predefined macros
#ifdef _WIN32 # include #else // Not Windows - assume we're on Unix # include #endif bool is_directory(const char* path) { #ifdef _WIN32 // Windows implementation #else // Unix implementation #endif }
On Windows, all the toolsets except the Cygwin port of GCC define the macro _WIN32; macros defined automatically in this way are known as predefined macros . Example 1-25 uses the predefined macro WIN32 to determine which operating system it is being compiled under and to enable the appropriate platform-specific code.
Often, however, the configuration information necessary to perform this kind of conditional compilation is not available as predefined macros. In such cases, it's necessary to introduce your own macros and to give them appropriate values using the methods shown in Table 1-15, Table 1-16, and Table 1-17. A good example is Example 1-2. On Windows, you want the function georgeringo( ) to be declared with the attribute _ _declspec(dllexport) when the DLL georgeringo.dll is being built, but with the attribute _ _declspec(dllimport) otherwise. As described in Recipe 1.4, you can achieve this effect by defining the preprocessor symbol GEORGERINGO_DLL from the command line when building the DLL, but not when compiling code that uses the DLL.
|
See Also
Recipe 1.4, Recipe 1.9, Recipe 1.12, and Recipe 1.17
Building C++ Applications
Code Organization
Numbers
Strings and Text
Dates and Times
Managing Data with Containers
Algorithms
Classes
Exceptions and Safety
Streams and Files
Science and Mathematics
Multithreading
Internationalization
XML
Miscellaneous
Index