The greatest mistake you can make in life is to be continually fearing you will make one

Monday 1 March 2010

C Preprocessor



  • The C preprocessor is a program that processes our source program before it is passed to the compiler.
  • preprocessor is a separate program which transforms C source code containing preprocessor directives into source code with the directives removed.
  • The preprocessor is implemented as an integral part of an Standard C compiler.
  • gcc -E filename will show the preprocessed file.
  • Preprocessor commands are known as directives.
  • Preprocessor works on a line by line basis.
  • The preprocessor doesn't know about the scope rules of C. Preprocessor directives like #define take effect as soon as they are seen and remain in effect until the end of the file that contains them
Preprocessor Directives:

  • The preprocessor commands are called as directives.
  • Each of these preprocessor directives begin with a # symbol.
  • The directives can be placed anywhere in a program but they are most often placed at the beginning of a program.
  • The  preprocessor directives are classified in to 4 major categories

    1. Macro Expansion(#define)
    2. File Inclusion(#include)
    3. Conditional Compilation
    4. Miscellaneous directives
  • The 2 most frequently used features are #include,to include the contents of a file during compilation and #define ,to replace a token by an arbitrary sequence of characters.
1.Macro Expansion:
  • C preprocessor provides a facility for defining constant and substitution,which are commonly called macros.
  • Macros are used when we want to make a program more readable or when we dont have enough information about certain values.
  • A macro definition has the form
         #define name replacement text
  • The statement above define a macro and some replacement text.The preprocessor will replace the name with the replacement text whenever the name is ocur in the source file.
  • The preprocessor directives are not C statements, so they do not end with semicolons.
  • Eg:
    #include<stdio.h>
    #define currency_rate 51
    int main()
    {
        int rs,money=500;
        rs=money * currency_rate;
        printf("RS=%d\n",rs);
        return 0;
    }
    So if the currency rate is changed we can make the necessary change inonly one place.
  • Any name may be defined with any replacement text.
    Eg
       #define forinfinite for(;;)
    defines a new word forinfinite for an infinite loop
  • A #define directive can be used to replace an operators or condition or even a entire statement
    Eg
    1.#define AND &&
    2.#define condition (a>25 AND a<50)
    3.#define print ("Welcome to my Blog");
  • Example Program


    #include<stdio.h>
    #define AND &&
    #define condition (a>25 AND a<50)
    #define PRINT printf("Welcome to my Blog\n");
    int main()
    {
        int a=40;
        if(condition)
            PRINT
        return 0;
    }
Macros with Arguments:
  • It is  also possible to define macros with arguments. so the replacement text can be different for different calls of the macro.
  • macros can have arguments just as functions can.
    Eg:   #define max(A,B) ((A)>(B)? (A) : (B)) Although it looks like a function call,a use of max expands in to inline code. Each occurance of a formal parameter A,B will be replaced by the corresponding actal arguemnt.
    so the statement  x=max(p+q,r+s); will be replaced by the line
        x=((p+q)>(r+s) ? (p+q) : (r+s));
  • commas are used to separate the arguments from each other and enclosing them with in parentheses
  • Example 1
    #define PRINT(a,b) printf("%s %s\n",a,b)
    PRINT("hello","welcome");

    Will result as
          printf("%s %s\n","hello","welcome");
  •  Example 2
    #define FUN(a,b) a b
    FUN(printf, ("%d %d %s\n",100,200,"hello"));

    results in
    printf ("%d %d %s\n",100,200,"hello");
Points to remember:
  1. A macro function is being processed when all of its arguments are identified.If any argument contains no preprocessor tokens then the behaviour is undefined. In the above example 2 FUN(,hello),FUN(xyz,) are undefined behaviour.
  2. Not to leave a blank between the macro template and its argument while defining the macro
    Example: There should be no blank space between AREA and (x) in the macro definition
    #define AREA(x) (3.14*x*x).
    If we write #define AREA (x) (3.14*x*x) then x will aso become a part of the macro .Then the statement area=AREA (10); expanded to area=(10) (3.14*10*10). which wont compile.
  3. some care should be taken with parentheses to make sure the order of evaluation is preserved.
    Consider the macro #define square(x) x*x .
    While the statement y=square(z+1) is invoked it will be evaluated as z+1*z+1. this will produce the wrong result as the * has higher precedence than +.
    The entire macro expansion should be enclosed with in parentheses.
    if y=64/square(4); is expanded then y=64/4*4 resulting y=64 but the expected result is 4.
  4. Macros can be split in to multiple lines with a '\'(back slash) present at the end of each line
    Eg:
    #define for_loop for(i=0;i<100;i++)\
                          printf("%d",i);
Difference between macros and function:
  1. In a macro call the preprocessor replaces the macro template with its macro expansion in a unthinking literal way.But in function call the control is passed to a function along with arguments,calculations are performed and useful value is returned back from the function.
  2. macros make the program run faster but increase the program size. but functions make the program smaller and compact.
  3. If a macro is simple and short then it makes a nice short hand and avoids the overheads associated with function calls.If the macro is very large and it is used often then the macro should be replaced with a function. 

1 comment: