Macros

  • Macro = a replacement rule specify how a input pattern must be replaced with an output pattern

  • Syntax to define a macro:

         #define <pattern>             <replacement pattern>  
         #define <pattern>(<params>)   <replacement pattern>
      

    Meaning:

      • Every occurence of the <pattern> in the text file will be replaced by the <replacement pattern>.

  • Common usage of macros in C programs:

      • Defining constants
      • Defining simple functions         

Defining symbolic constants in C

Symbolic constants in C programs are defined using a macro:

  • C program:

    
       #define PI   3.14159265358979    // Symbolic constants
       #define MAX  99999
    
       int main( int argc, char* argv[] )
       {
          int x;
          double y;
    
          x = MAX;
          y = PI;
    
          for ( i = 0; i < MAX; i++ )
             z = k * sin( i * PI );
       } 

Defining symbolic constants in C

After processing by the C pre-processor, the C program will be transformed to:

  • C source:

      
       // The #define lines will be removed
       // after the pre-processing step
    
       int main( int argc, char* argv[] )
       {
          int x;
          double y;
    
          x = 99999;
          y = 3.14159265358979;
    
          for ( i = 0; i < 99999; i++ )
             z = k * sin( i * 3.14159265358979 );
       } 

DEMO: /home/cs255001/demo/c/1-C-pre/define1.c     ---    gcc -E define1.c

Macros with parameters:    Defining simple (one-line) functions

  • You can also use use the #define macro construct to define simple (one line) functions

  • Example:

    
     #define square(x)   (x*x)   // Note: there is a problem !! 
    
     int main( int argc, char* argv[] )
     {
        double a, b;
    
        b = square(a);
     }
      

DEMO: /home/cs255001/demo/c/1-C-pre/define2.c     ---    gcc -E define2.c

Macros with parameters:    Defining simple (one-line) functions

  • You can also use use the #define macro construct to define simple (one line) functions

  • After processing by the C pre-processor, the C program becomes:

    
     #define square(x)   (x*x)   // Note: there is a problem !! 
    
     int main( int argc, char* argv[] )
     {
        double a, b;
    
        b = a*a;
     }
      

Macros with parameters:    Defining simple (one-line) functions

  • Be careful when you define macros with parameters:

      • Operator precedence can alter the meaning that you intended

  • Example:

    
     #define square(x)   (x*x)   // Note: there is a problem !! 
    
     int main( int argc, char* argv[] )
     {
        double a, b, c;
    
        c = square(a+b);  // Intension: compute (a+b)2
     }
      

Macros with parameters:    Defining simple (one-line) functions

  • Be careful when you define macros with parameters:

      • Operator precedence can alter the meaning that you intended

  • After processing by the C pre-processor, the C program becomes:

    
     #define square(x)   (x*x)   // Note: there is a problem !! 
    
     int main( int argc, char* argv[] )
     {
        double a, b, c;
    
        z = (a+b*a+b);    //  a+b*a+b = a+(b*a)+b ≠ (a+b)2 !! 
     }
      

Macros with parameters:    Defining simple (one-line) functions

  • Solution:

      • Always use braces (...) around every parameter in the macros

  • Example:

    
     #define square(x)   ((x)*(x))  
    
     int main( int argc, char* argv[] )
     {
        double a, b, c;
    
        c = square(a+b);    
     }
      

Macros with parameters:    Defining simple (one-line) functions

  • Solution:

      • Always use braces (...) around every parameter in the macros

  • After processing by the C pre-processor, the C program becomes:

    
     #define square(x)   ((x)*(x))  
    
     int main( int argc, char* argv[] )
     {
        double a, b, c;
    
        c = ((a+b)*(a+b));    
     }
      

Undefining a macro

 

  • You can undefine a macro using:

      #undef  macro-name
      

  • Example:

      #undef   PI
      #undef   MAX
      #undef   square     // Omit the parameters !