C compiler has three phases in the compilation and building and they are - Pre-processing, compilation and linking. Pre-processing is the stage of compilation which does a major protion of content importing and replacement work. C has these pre-processor directives available.

#include
#define
#undef
#line
#error
#pragma
#
#if
#else
#endif 
 
#ifdef
#else 
#endif

#ifndef
#else
#endif

#include – It includes a header or source file content into the existing file. Pre-processor imports entire content of the file to this sourec file. It then passes the expanded content to the compiler.

Syntax:
#include <file relative path> or
#include "<absolut path>"
Example-
#include <stdio.h>
#include "myheader.h"

#if – This is like a if statement in C. In "if" block -If the condition satisfies the block of the code under if comes into execution. Similarly here the block of code comes under compilation. There are also similar directives #ifdef and #ifndef available in same context. #ifdef checks if a symbol is defined and #ifndef checks if symbol is not defined. #else – Else block portion of compilation. It should have a #if/#ifdef/#ifndef block first. #endif – Ends the #if/#ifdef/#ifndef block. It can be placed after #if/#ifdef/#ifndef or after #else part.

Syntax:
#if/#ifdef/#ifndef <SYMBOL Name>
statement(s);
#endif

#if/#ifdef/#ifndef <SYMBOL Name>
statement(s);
#else 
statement(s);
#endif

Example-
#if 0
statement(s); /* Not Under compilation */
#else 
statement(s); /* Under compilation */
#endif

#ifdef DEBUG
const char version [] = "1.0.debug";
#else 
const char version [] = "1.0.release";
#endif

#ifndef __cplusplus
#error "Please compile with C++ compiler only."
#endif

#define – Defines a new maro. Macro can be in the form of any expression or statements. When used in any place, pre-processor expands the symbol with defined expressios or statements.

#define <Macro Name> <Expression or Statement(s)>
#define PI (3.14)

#undef – This does the reverse of #define. This is to remove/discard the previous definition.

#undef <Macro/symbol Name>
#undef PI 

#line – redefines the line number of the file during compilation.

#line <line no.> <relative or absolute path>
#line 10

#error – Sets compilation error flag and the string/message given next to it goes to the compiler output messages.

#error "<Error message>";
Example-
#ifndef __cplusplus
#error "Please compile with C++ compiler only."
#endif

#pragma – Pragma has multiple use. It is used to set many compiler options. Difining packing of structure is one of very frequently used.

#pragma pack (4)
#pragma pack (push, 4)
#pragma pack pop

Macro directive is very common in C programs. We are disscussing many aspects of this.
Macro is a statement that may be defined in include files or before the function where it is used. Macro can be a constant number or string or multiple C statements or any expression in C. During preprocessing, the preprocessor replaces every occurrence of the macro with the statement defined in it.

Syntax:
#define <Macro Name> <Expression or Statement(s)>
Example-
#define CONST 25

This statement defines a Constant CONST with value 25.
CONST is called a macro template while 25 is the macro expansion. They are seperated by a space and has no terminating semi-colon(;)

Advantages of Macro:
  1. Makes the program easier to read
  2. If the value of a constant changes, a change made to the macro expansion is enough to change the value throughout the program.
  3. If a constant is defined with a macro, it generated faster and creates more compact codes than using variables
  4. If a constant is defined as a variable, its value may change in the program without the programmer being aware
How Macro Works?

During compilation, the code is processed by the C-Preprocessor before being passed onto the Compiler. The preprocessor scans the code for any macro definition. Whenever it finds a #define directive, it searches the entire program for macro templates and on finding them, replaces them with the proper macro expansion. The program is handed over to the compiler when this process completes.

Common Uses

A #define directive may be used to define operators as shown below.

#define AND &&
int main (int argc, char *argv[])
{
  int f = 1, x = 4;
  if ((f < 5) AND (x < 4)) {
    printf ("\n Hello World");
  } else {
    printf ("\n Hello Universe");
  }
}

A #define directive may be used to replace a condition as shown below.

#define RANGE (x > 0 && x < 4)
int main (int argc, char *argv[])
{
  int x = 4;
  if (RANGE) {
    printf ("\n Within Range" );
  } else {
    printf ("\n Outside range");
  }
}

A #define directive may be used to replace C statement as shown below.

#define STATEMENT printf ("\n Value Found");
int main (int argc, char *argv[])
{
  int x = 4;
  if (x == 3) {
    STATEMENT
  } else {
    printf ("\n not found");
  }
}

Macro with Arguments

The simple macros used so far required no arguments. But macros may take arguments. Examples are shown below.

#define SQR(x) (x * x)
int main (int argc, char *argv[])
{
  int a = 4, s;
  s = SQR(a);
  printf ("Square of %d is %d", a, s);
}

Output of the program:
Square of 4 is 16

In this program, whenever the preprocessor finds the statement SQR(x) it expands it to the statement ( x * x ). Also, since the argument in the macro template SQR(x) matches the symbol in macro expansion ( x * x ), the statement SQR(a) causes substitution of x by a. Thus the statement becomes ( a * a ).

After the code pases through the preprocessor, it is expanded to the following:

int main (int argc, char *argv[])
{
  int a = 4, s;
  s = a * a;
  printf ("Square of %d is %d", a, s);
}

Points to remember:

  1. There should be no blank between macro template and argument.
    Example:SQR(x) not SQR (x)
  2. The entire macro expansion should be enclosed in brackets

Difference between Macros and Functions

  1. In a macro call, the preprocessor literally replaces the macro template with the macro expansion. Whereas, in a function call, the control passes to a function with some arguments, some calculations are performed by the function and a value is returned.
  2. If a macro is used in the program lots of times, the macro expansion goes to the source code at that many places, effectively increasing the program size. However, a function call, even if made several times, take the same amount of time.

About our authors: Team EQA

You have viewed 1 page out of 252. Your C learning is 0.00% complete. Login to check your learning progress.

#