Difference between Preprocessor Directives and Macro
Preprocessor Directives
Introduction
-
- The C pre-processor is not part of the compiler but is a separate step in the compilation process.
- The syntax of the pre-processor is different from the syntax of the rest of the C program in several respects.
Definition
-
- Preprocessor directives in C are instructions that are processed by the preprocessor before the actual compilation of code begins.
- C pre-processor is just a text substitution tool, which filters our source code before it is compiled.
- Preprocessor directives allow us to control how our program is compiled, making them very useful for defining constants, macros, conditional compilation, and improving code portability.
Features/Characteristics
-
- The pre-processor is a translation phase that is applied to the source code/program before the compiler gets its hands on it.
- They provide a way to include files, define constants, macros, and control conditional compilation.
- It is a very powerful tool for the programmer.
- All pre-processor directives or commands are indicated by a
#
symbol at the beginning of a line.
Types of Pre-processor Directives
-
- The pre-processor directives perform textual substitutions during the compilation time in our source code. On this basis, they are of three types –
- File Inclusion: Inserting the contents of another file into our source file, as if we had typed it all in there. For example – #include.
- Macro Substitution: Replacing instances of one piece of text with another. For example – #define.
- Conditional Compilation: Depending on various circumstances, certain parts of the source code are seen or not seen by the compiler at all. For example – #if, #if-#else, etc.
- The pre-processor directives perform textual substitutions during the compilation time in our source code. On this basis, they are of three types –
Advantages
-
- The preprocessor makes programs easier to develop, read and modify.
- The preprocessor makes C code portable between different machine architectures & customizes the language.
- The preprocessor allows us to customize the language.
Lists of Pre-processor Directives
#include
-
- The #include directive is used to include the contents of a file (usually a header file) into the current source file for their definition for the compiler.
- Syntax
-
- Example
#define
-
- The #define directive is used to define macros or symbolic constants used in the program.
- It can also be used to define/create function-like macros.
- In #define preprocessor, the literal is substituted by literal value/constant at every occurrence, before compilation of the program.
- No semicolon (;) needs to be placed as the delimiter at the end of a # define line.
- Syntax
-
- For Example –
(Here, the C preprocessor simply searches through the C code before it is compiled and replaces every instance of PI, MAXSIZE, and SQUARE(x) with 3.14159, 20, and x*x respectively.)
Here, the preprocessor replaces all occurrences of PI with 3.14159 and MAXSIZE with 20. SQUARE(x) is a macro that calculates the square of x.
#undef
-
- The #undef directive is used to undefine a previously defined macro.
- Once a macro is undefined, it is no longer available.
- Syntax
-
- Example
#ifdef and #ifndef
-
-
Both Macros check if a macro is defined(#ifdef) or not defined(#ifndef).
- #ifdef: The code inside this block is compiled only if the specified macro is defined.
- #ifndef: The code inside this block is compiled only if the specified macro is not defined.
- Syntax
-
-
- Example
#if, #elif, #else, and #endif
-
- These directives allow conditional compilation based on expressions.
- Syntax
-
- Example
#pragma
-
- The #pragma directive provides additional compiler-specific instructions.
- It is used to control the behavior of the compiler, such as disabling warnings.
- Syntax
#pragma directive-name
-
- Example
#error
- The #error directive causes the preprocessor to generate an error message and halt the compilation.
- Syntax
- Example
#line
-
- The #line directive changes the current line number and optionally the filename for debugging purposes in the preprocessor output.
- It’s mainly used for debugging.
- Syntax
#line number “filename”
-
- Example
__FILE__ and __LINE__ Predefined Macros
- These are special predefined macros that give information about the current file and line number during compilation.
- For example –
Macros
Introduction
-
- Macros are symbolic constants and compile time functions.
- Macros are string replacement techniques commonly used to define constants.
Definition
-
- Macros in C is a way to define constants, functions, or code blocks that get substituted into the program at compile time. They are defined using the #define preprocessor directive.
- A macro is a segment of code that is replaced by the value of a defined macro.
- Macros are one of the Pre-processor directives available in C.
Syntax
Here, #define is a type of macro/Pre-processor directives, the identifier is a macro name and the string a macro replacement.
-
- To create/define a macro :
- The above syntax statement is included in the program at the beginning(above main() with other header files), and then the pre-processor automatically replaces every occurrence of the identifier in the source code with the string value.
- To create a macro, the keyword #define is written followed by the identifier name and a string value with at least one blank space between them (as in syntax).
- The definition is macro is not terminated by a semicolon(;) symbol as a line terminator.
- The string value may be any constant/expression while the identifier name must be a valid C name in capital letters.
- We can also use macro defined in the system standard libraries such as ‘abs’, which returns the absolute value of its parameter. Again, we can also create/define our version of a customized ABS macro similar to the system-defined macro but with a different identifier name such as ABS (system-defined is abs) to avoid conflicting with the existing name abs in the system standard library.
- To create/define a macro :
#define ABS(x) ((x) < 0) ? – (x) : (x)
-
- To Disable/Undefining a Macro :
- A defined macro can be disabled/undefined, using the #undef statement.
- Syntax :
- To Disable/Undefining a Macro :
#undef identifier(name)
-
-
- This option is applied when we want to restrict the definition of macro only to a particular region/part of the program.
-
Example
It sets the value of identifier MAX to 200 and whenever we want to use 200 in our program we can put MAX instead of writing 200 which is later substituted by the compiler at the proper place with its value/constant. In other words, Whenever we want to use the value of MAX in our program segment code we can simply write MAX instead of writing a lengthy value of MAX again and again. We can put/use multiple times MAX in our program code as per the need of the program.
Features/Characteristics
-
- It is a pre-defined symbol with or without parameters.
- We can create our own macros with the #define pre-processor directive.
- When we use the macro, its value (with the actual parameters) is substituted at the location in the program where we use it.
- We can create our own customized macro as per the logic/need of the program or can also use system-defined standard library macro in our program.
- Macros are inline code, which is substituted at compile time.
- All the macros are replaced with their definitions during compile time.
- Macro substitution is a process where an identifier in a program is replaced by a predefined string by the pre-processor.
- Macros can also accept parameters and return values. These macros are called Macro Functions.
- The Main use of Macro is not to solve this type of program rather it is often used to create codes that can be compiled on different machines.
- Macros work similarly as a function but with few differences
- Macros are implemented as a textual substitution, therefore by this the performance of the program improves compared to functions
- Recursive macros generally do not suggest to use of like functions.
- Macros don’t care about the data type of their arguments. Hence macros are a good choice where we want to operate on reals, integers, or a mixture of the two.
- Macros are generally fairly small.
Types of Macro Substitutions
-
- There are different types of macro substitution. These are:-
(a) Simple Macro Substitution :
-
-
- They are simple string replacements with defined identifiers.
- They are also called ‘Object like Macro’.
- They are widely used macro.
- For example –
-
(b) Argumented Macro Substitution :
-
-
- This type of Macro allows us to define more complex and more useful forms of replacements.
- They are also called ‘Functions like Macro’ because they work like a function call.
- Syntax :
-
#define identifier(f1,f2,..,fn) string
-
-
-
For example
-
-
(c) Nested Macro Substitution :
-
-
- Here, we can use one/more macros in the definition of another macro as per the logic/need of the program.
- For example –
-
Advantages
-
- Macros can make long, ungainly pieces of code into short words.
- It increases the execution speed of the code because there is no function call overhead.
- They are used to avoid repetitive codes and some dependencies in the program.
Disadvantage
-
- Macro is used carefully, taking in mind the order of precedence of operators, especially arithmetic type.
- Macros don’t show debugger results correctly or are less clear.
Use of Macro
-
- Constant Definition: Macros are used to define constants for values like PI.
- Function-like Macros: Macros can be used to perform small, reusable operations like functions such as SQUARE(x) or MAX(a, b).
- Conditional Compilation: They are used to include/exclude parts of code in the program such as #ifdef, #endif, and similar macros.
- Code Reusability: They are used to define frequently used code blocks like SWAP(a, b) to reduce redundancy.
- Error Handling: Macro simplifies error checking and reporting.
0 Comments