Wednesday, 15 February 2012

Preprocessor Directives, complete reference for programming in C and C++

Preprocessor Directives

These in C++ are the inbuilt files/code provided to a programmer that are included to handle source file inclusion (#include), macros definition (#define) & conditional inclusion (#if).
They are not actually program statements but can be assumed to be the most important part of the program. These are basically directives for preprocessor i.e. these files direct the processor for preprocessing needed to run a program in C++ successfully. These files are always included in a program with a (#) sign preceding their names. And the most important thing about these directives is that there should be no (;) succeeding their names. The statement of including a particular preprocessor directive will be over after a newline character backslash (\) is encountered.

Types of Preprocessor

There are basically 6 types of preprocessor directives namely:
  1. Macros definitions (#define,#undef): #define is used to define preprocessor macros while #undef is used to undefined these.

    The default format for its definition is as below:
     #define identifier replacement
    What the macros actually do is they replaces identifier by replacement in the whole program followed by these macros. e.g.
    #define TABLE_SIZE 100
    int table1[TABLE_SIZE];
    int table2[TABLE_SIZE];

    The above code will be equivalent to after the replacement of the table size with 100 throughout the program:
    int table1[100];
    int table2[100];
    Note:  A macro will show its existence in a program until the user it will undefine it with #undef preprocessor directive.  e.g.
    #define TABLE_SIZE 100
    int table1[TABLE_SIZE];
    #undef TABLE_SIZE
    #define TABLE_SIZE 200
    int table2[TABLE_SIZE];

    The above code will generate the same output as:
    int table1[100];
    int table2[200];

    Replacement can be preceded by two special characters (# and ##):
    If  the replacement is preceded by #, than the compiler will treat the replacement as string.  For an instance:
    #define str(x) #x
    cout << str(test);

    The above code after compilation will be equivalent to:
    cout << "test";

    And if ## is encountered between replacements in macros than the compiler will concatenate the two replacements throughout the program. For instance:
    #define glue(a,b) a ## b
    glue(c,out) << "test";
    The above code after compilation will be :
    cout << "test";

    Caution: Be careful while dealing with macros because they can change the whle program in a sec.

  2. Conditional inclusions(#ifdef,#ifndef,#if,#endif,#else,#elif): These inclusions are mainly used to allow or disallow a part of a particular program for execution based on the evaluation of certain conditions.
    The first one #ifdef is used for allowing or discarting the compilation of a certain code/statements on checking condition that whether the macro used in any other statement s previously defined with #defne or not.e.g:
    #ifdef TABLE_SIZE
    int table[TABLE_SIZE];
    #endif
    The 2nd line here will only be compiled if the macro used in that line TABLE SIZE is defined previously in the instructions preceeding #ifdef condition in the program.

    While the second inclusion operator #ifndef does work exactly opposite to that of #ifdef. It will allow excution of the statements including macros only if the macro is not defined already in the program.
    The above 2 operators works only if the statements containing macros preceded with conditions and suceeded with #endif which is used to terminate the above conditions.
    Rest of the operators which are #if, #elif 7 #else are used to allow the compilation of a group of stataments based on some specific condition which are covered with the above conditional inclusions.
    But these statements are also to be ended by #endif.

  3. Line control(#line):This inclusion is used generally for easy error detection in a program. We can also define the file name with line number to be shown when an error will be detected in the program.
    e.g:
    #line 20 "assigning variable"
    int a?;
    The code written above will generate error as :  error in file “assigning variable”,line 20
       
  4. Error directive(#error):A user can use this directive to abort the compilation in a program whenever required. Also the user can define the error to be generated or shown while aborting the compilation. But this directive will be used with the conditional inclusions as shown below:
    e.g:
    #ifndef __cplusplus
    #error A C++ compiler is required!
    #endif
    The above code will generate an error if the name of  macro __cplusplus is already  not defined in the program above the #ifdef condition as:  A C++ compiler is required, which is defined between #ifdef & #endif condition.


  5. Source file inclusion(#include):This type of inclusion in preprocessor directive is used for including the standard or user defined header files in a program. Whenever this code #include will be encountered followed by a file name the file will be replaced with the whole data in the file name given.
    The two syntax of the using this type of inclusion is depicted below:
    #include "file"
    #include <file>
    But there is a minor difference between the two syntax. The second syntax will look/search for the header files in the default directories for standard library files. But the first syntax will look/search for the library files in directive containing the programmed file first, if it is found there it’s OK. But if it is not found there it will then search the files in the default standard library files directory.

  6. Pragma directive(#pragma):Pragma directive preprocessor type is compiler based. It is included to  perform various operations whose number is dependent on the no of instructions that can be suffixed with this inclusion supported by the compiler. In addition to the compiler, it also depends on the platform a programmer is programming.
Some of the predefined macro’s that can be defined any time in C++ are shown below with their functions they perform:

 An example program showing the use of the above macros is
: // standard macro names
#include <iostream>
 using namespace std;
 int main()
{
cout << "This is the line number " << __LINE__;
  cout << " of file " << __FILE__ << ".\n";
  cout << "Its compilation began " << __DATE__;
cout << " at " << __TIME__ << ".\n";
  cout << "The compiler gives a __cplusplus value of " << __cplusplus;
 return 0;
 }

 This program will generate the output as:  This is the line number 7 of file /home/jay/stdmacronames.cpp. Its compilation began Nov  1 2005 at 10:12:29. The compiler gives a __cplusplus value of 1 NOTE:If a compiler doesn’t support a particular macro, it will not generate any error in the compilation, just ignore it. So that’s all about the preprocessor directives in C++ which are used in the programming for various purpose. 

No comments:

Post a Comment