Functions and Directives

Directive #ifdef Foundation

Compiles code when a symbol is defined

Syntax
#ifdef <Symbol>
   <SourceCode>...
[ #else
   <SourceCode>...
]
#endif
Parameters
<Symbol>
<Symbol> designates a preprocessor constant which was defined with the #define directive or with the /D compiler switch.
Description

The directives #ifdef...#else...#endif form a control structure for the preprocessor. When the preprocessor constant <Symbol> has been defined previous to the preprocessor encountering the #ifdefdirective, the preprocessor translates and outputs the source code located between the directives #ifdef and #else to the intermediary file. If no #else directive is present, the preprocessor translates and outputs the source code located between the directives #ifdef and #endif.

#ifdef provides support for conditional compilation. The preprocessor translates the source code subsequent to the directive #ifdef only when the preprocessor constant <Symbol> has been previously defined. If this constant has not been defined the preprocessor translates the source code which is between the #elseand #endif directives. Whichever block of code the preprocessor ignores does not get translated and output to the intermediary file, and thus does not get compiled.

Conditional compilation is performed primarily during application development. Generally, the directives #ifdef and #endif are used to frame blocks of code that perform special error assertions. The #ifdef directives typically test for a #define constant indicating that DEBUG operations are ongoing. When debugging is completed, the special assertions are not required, and simply removing a single #define DEBUG statement in a master Include file and performing an application-wide recompile is all that is necessary to remove all assertion code.

Examples
#ifdef showing assertion usage

// In this example, the pseudofunction  ASSERT() is programmed 
// with the directive #translate. The function is inserted during 
// application development for testing the validity of function 
// parameters or other program conditions which must be verified so that 
// a program runs error free. When the preprocessor constant DEBUG 
// is not defined with  #define, the pseudofunction is removed 
// from the compiled program. The file TEST.PRG demonstrates this: 

******************* 
* File ASSERT.CH * 
******************* 
#ifdef DEBUG 

   #translate ASSERT( <condition> [, <message>] ) ; 
         =>   IF .NOT. (<condition>) ;; 
                 QOut( "Error in:", ProcName(0) ) ;; 
                 QOut( "    Line:", ProcLine(0) ) ;; 
                 QOut( #<message> )  ;; 
                 QUIT ;; 
              ENDIF 
#else 

   #translate  ASSERT( <Exp> [, <Msg>] )   => 

#endif 
////// 
// EOF 
////// 

****************** 
* File TEST.PRG * 
****************** 
#include "Assert.ch"                     // Include file 

#ifdef DEBUG                             // Message is displayed 
   #stdout DEBUG version                 // during compilation 
#endif 

FUNCTION UpperLower( cString )           // Parameter test with 
                                         // pseudofunction 
   ASSERT( .NOT. Empty(cString), "Function UpperLower()" ) 

RETURN  Upper( Left(cString,1) ) + ; 
        Lower( SubStr(cString,2) ) 
////// 
// EOF 
////// 

// The file TEST.PRG is shown compiled with two compiler 
// switches. The preprocessor constant DEBUG is defined using 
// the /d switch. The switch /p generates the file TEST.PPO 
// (preprocessed output file). 

XPP test /dDEBUG /p 

// The file TEST.PPO contains the code which was preprocessed. 
// (long statements have been edited to span multiple lines in 
// this sample) 

****************** 
* File TEST.PPO * 
****************** 
FUNCTION UpperLower( cString ) 

   IF .NOT. (.NOT. Empty(cString)); 
       QOut( "Error in:", ProcName(0) ) ; 
       QOut( "    Line:", ProcLine(0) ) ; 
       QOut( '"Funktion UpperLower()"' ) ; 
       _quit(); 
   ENDIF 

RETURN  Upper( Left(cString,1) ) +  Lower( SubStr(cString,2) ) 

// When the file  TEST.PRG is compiled without the preprocessor 
// constant DEBUG being defined, TEST.PPO contains the following 
// code: 
****************** 
* File TEST.PPO * 
****************** 

FUNCTION UpperLower( cString ) 

RETURN  Upper( Left(cString,1) ) +  Lower( SubStr(cString,2) ) 

Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.