Conditional pre-processing

  • The C preprocessor provide these conditional pre-processing directives:

      Conditional directive         Meaning
      ==========================================================
      #ifdef   Name               Pre-process ... when 
      ...                         "Name" has been #defined
      #endif
    
      #ifndef   Name              Pre-process ... when 
      ...                         "Name" has not been #defined
      #endif
    
      #if Condition               Pre-process ... when 
      ...                         "Condition" is true
      #endif 

  • I will not discuss the

      #if Condition    

    clause because it is rarely used.

The #ifdef conditional pre-processing directive

  • Syntax of the #ifdef conditional directive:

      #ifdef   NAME-1
         text segment 1        
     [#elif    NAME-2
         text  segment 2]  
      ...     
     [#else
         text segment 3]
      #endif 

  • Meaning:

      • If NAME-1 was #defined, then the C pre-processor will process text segnment1
      • Otherwise, if NAME-2 was #defined, then the C pre-processor will process text segnment2
      • And so on (if you have more #elif directives)
      • Otherwise, the the C pre-processor will process text segnment3

Example of using the #ifdef conditional directive

  • I personally like to use ifdef around print( ) statements that I use for debugging:

      #define DEBUG   // This defines DEBUG = empty string 
    
      int main( )
      {
          int x, y;
    
          x = 3;
          y = 4;
    
    
          #ifdef DEBUG
          printf("x = %d\n", x);  // Print variable x for debugging
          printf("y = %d\n", y);  // Print variable x for debugging
          #endif
      }
      

  • When I want the C program to print out debug information, I would #define DEBUG at the top of my program

Example of using the #ifdef conditional directive

  • The conditional directive will generate the following C source:

     
    
      int main( )
      {
          int x, y;
    
          x = 3;
          y = 4;
    
    
    
          printf("x = %d\n", x);  // Print variable x for debugging
          printf("y = %d\n", y);  // Print variable x for debugging
    
      }
      

    and the C program will print out the variables so I can check and find bugs

DEMO: demo/C/1-C-pre/ifdef1.c

Example of using the #ifdef conditional directive

  • When I do not want to see the debug information, I would rename the macro-name:

      #define DEBUGx  // Now DEBUG is not defined !
    
      int main( )
      {
          int x, y;
    
          x = 3;
          y = 4;
    
    
          #ifdef DEBUG
          printf("x = %d\n", x);  // Print variable x for debugging
          printf("y = %d\n", y);  // Print variable x for debugging
          #endif
      }
      

Comment: there is an even better way to manage printing of debug messages!

Example of using the #ifdef conditional directive

  • The conditional directive will generate the following C source:

     
    
      int main( )
      {
          int x, y;
    
          x = 3;
          y = 4;
    
    
    
        
         
    
      }
      

    and the C program will not have print( ) statements for debugging

The define symbol C compiler option

  • The C compiler has a define symbol compile option that allow you to define a macro name before the C compiler translates a C program

  • C compiler syntax for the define symbol option:

      gcc  -Dmacro[=pattern]  ......

  • The C program does not contain the #define DEBUG directive:

    int main( )
    {
       int x = 3, y = 4;
    
       #ifdef DEBUG
       printf("x = %d\n", x);  // Print variable x for debugging    
       printf("y = %d\n", y);  // Print variable x for debugging
       #endif
    }

  • To include the print( ) statement, compile with:   gcc -DDEBUG prog.c

DEMO: demo/C/1-C-pre/ifdef2.c

The #ifndef conditional pre-processing directive

  • Syntax of the #ifndef conditional directive:

      #ifndef   NAME-1
         text segment 1        
     [#elif    NAME-2
         text  segment 2]  
      ...     
     [#else
         text segment 3]
      #endif 

  • Meaning:

      • If NAME-1 was not #defined, then the C pre-processor will process text segnment1
      • Otherwise, if NAME-2 was not #defined, then the C pre-processor will process text segnment2
      • And so on (if you have more #elif directives)
      • Otherwise, the the C pre-processor will process text segnment3

Common use of the #ifndef conditional directive

  • The #ifndef conditional directive is commonly used to prevent multiple inclusion of the same header file

  • Commonly used technique in C programming

    • The #ifndef conditional directive can break a recursive include chain of include files


    I will show you how in the next set of slides