10.2 Conditional Compilation

I l @ ve RuBoard

One problem programmers have is writing code that can work on many different machines. In theory, C++ code is portable; in practice, many machines have little quirks that must be accounted for. For example, this book covers Unix, MS-DOS, and Windows compilers. Although they are almost the same, there are some differences.

Through the use of conditional compilation , the preprocessor allows you great flexibility in changing the way code is generated. Suppose you want to put debugging code in the program while you are working on it and then remove the debugging code in the production version. You could do this by including the code in an #ifdef - #endif section, like this:

 #ifdef DEBUG      std::cout << "In compute_hash, value " << value << " hash " << hash << "\n";  #endif /* DEBUG */ 

You do not have to put the /* DEBUG */ after the #endif , but it is very useful as a comment.

If the beginning of the program contains the following directive, the std::cout is included:

 #define DEBUG       /* Turn debugging on */ 

If the program contains the following directive, the std::cout is omitted:

 #undef DEBUG        /* Turn debugging off */ 

Strictly speaking, the #undef DEBUG is unnecessary. If there is no #define DEBUG statement, DEBUG is undefined. The #undef DEBUG statement is used to indicate explicitly to anyone reading the code that DEBUG is used for conditional compilation and is now turned off.

The directive # ifndef causes the code to be compiled if the symbol is not defined:

 #ifndef STACK_SIZE /* Is stack size defined? */ #define STACK_SIZE 100 /* It's not defined, so define it here */ #endif /* STACK_SIZE */ 

#else reverses the sense of the conditional. For example:

 #ifdef DEBUG      std::cout << "Test version. Debugging is on\n";  #else /* DEBUG */     std::cout << "Production version\n";  #endif /* DEBUG  */ 

A programmer may wish to temporarily remove a section of code. A common method of doing this is to comment out the code by enclosing it in /* */. This can cause problems, as shown by the following example:

 /***** Comment out this section      section_report(  );      /* Handle the end-of-section stuff */      dump_table(  );  **** End of commented out section */ 

This generates a syntax error for the fifth line. Why? Because the */ on the third line ends the comment that started on the first line, and the fifth line :

 **** End of commented out section */ 

is not a legal C++ statement.

A better method is to use the #ifdef construct to remove the code.

 #ifdef UNDEF      section_report(  );      /* Handle the end-of-section stuff */      dump_table(  );  #endif /* UNDEF */ 

(Of course the code will be included if anyone defines the symbol UNDEF ; however, anyone who does so should be shot.)

The compiler switch -D symbol allows symbols to be defined on the command line. For example, the command:

 CC -DDEBUG -g -o prog prog.cc 

compiles the program prog.c and includes all the code in #ifdef DEBUG/#endif /* DEBUG */ pairs, even though there is no #define DEBUG in the program. The Borland-C++ equivalent is:

 bcc32 -DDEBUG -g -N -eprog.exe prog.c 

The general form of the option is -D symbol or -D symbol = value . For example, the following sets MAX to 10:

 CC -DMAX=10 -o prog prog.c 

Most C++ compilers automatically define some system-dependent symbols. For example, Borland-C++ defines the symbol _ _BORLANDC_ _, and Windows-based compilers define _ _WIN32 . The ANSI standard compiler C defines the symbol _ _STDC_ _ . C++ compilers define the symbol _ _cplusplus . Most Unix compilers define a name for the system (e.g., Sun, VAX, Linux, etc.); however, they are rarely documented. The symbol unix is always defined for all Unix machines

Command-line options specify the initial value of a symbol only. Any #define and #undef directives in the program can change the symbol's value. For example, the directive #undef DEBUG results in DEBUG being undefined whether or not you use -DDEBUG .

I l @ ve RuBoard


Practical C++ Programming
Practical C Programming, 3rd Edition
ISBN: 1565923065
EAN: 2147483647
Year: 2003
Pages: 364

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net