Back to: C Tutorials For Beginners and Professionals
Conditional Compilation Directives in C
In this article, I will discuss the Conditional Compilation Directives in C with Examples. Please read our previous article discussing File Inclusion Directives in C. At the end of this article, you will understand what Conditional Compilation Directives in C are and when and how to use Conditional Compilation Directives in C Programs with examples.
Conditional Compilation Pre-Processor Directives in C:
Conditional Compilation Directives in C are a set of preprocessing directives that allow us to include or exclude parts of a program based on certain conditions. These directives are processed before the actual compilation of the code. These are useful for making a program portable across different platforms or including debug and release versions within the same code base. Here are the key conditional compilation directives in C:
- #if: This directive tests if a certain condition is true. If the condition evaluates to true, the compiler includes the code between #if and the next #endif, #else, or #elif directive.
- #ifdef: This checks if a macro is defined. If the macro is defined, the code following #ifdef up to #endif, #else, or #elif is compiled.
- #ifndef: Opposite of #ifdef. It checks if a macro is not defined. If the macro is not defined, the code following #ifndef is compiled.
- #else: Used with #if, #ifdef, or #ifndef. If the preceding condition is false, the compiler includes the code following #else.
- #elif: Short for “else if”. Allows for multiple conditional expressions. If the preceding #if, #ifdef, or #ifndef is false, and the condition in #elif is true, the code following #elif is compiled.
- #endif: Marks the end of a conditional compilation block started by #if, #ifdef, #ifndef, #else, or #elif.
- #define: Used to define macros, which can be used in conditional compilation.
- #undef: Used to undefine macros.
In this technique, the pre-processor depends on the conditional block name to be passed from the compilation process or not, which is decided at the time of pre-processing. The block will be passed from the compilation process if the condition is true. If the condition is false, then the complete block of the statements will be removed from the source at the time of the pre-processor.
The basic advantage of this pre-processor is reducing .exe file size because when source code is reduced, then automatically object code is reduced, so exe file size also will be reduced. Let us see an example for understanding this concept.
#if Conditional Compilation Directive Example in C
The #if directive in C is used for conditional compilation. The compiler evaluates the condition; if the condition is true (non-zero), the code following the #if up to the next #endif, #else, or #elif is compiled. Otherwise, it is skipped. This is particularly useful for including code only in certain compile-time conditions, like debugging or targeting specific platforms. Here’s an example to demonstrate the usage of #if, #else, and #endif:
#include <stdio.h> #define LEVEL 2 int main() { #if LEVEL > 0 printf("Basic level.\n"); #endif #if LEVEL > 1 printf("Intermediate level.\n"); #endif #if LEVEL > 2 printf("Advanced level.\n"); #else printf("Not advanced level.\n"); #endif return 0; }
In this example:
- The macro LEVEL is defined with a value of 2.
- The #if LEVEL > 0 condition is true, so “Basic level.” is printed.
- The #if LEVEL > 1 condition is also true, so “Intermediate level.” is printed.
- The #if LEVEL > 2 condition is false, so the code under this #if is skipped, and the #else part is executed, printing “Not advanced level.”.
When you run the above code, you will get the following output:
#ifdef Conditional Compilation Directive Example in C
The #ifdef directive in C checks if a certain macro is defined before compiling a portion of code. This is particularly useful for making your code adaptable to different environments or conditions without changing the source code. Here’s an example to illustrate how #ifdef is used:
#include <stdio.h> // Define a macro for a specific condition #define DEBUG_MODE int main() { printf("Starting program...\n"); // Conditional compilation #ifdef DEBUG_MODE // This code block will only compile if DEBUG_MODE is defined printf("Debug mode is enabled.\n"); // Debug-related code goes here #else // This code block will compile if DEBUG_MODE is not defined printf("Running in normal mode.\n"); #endif // Rest of the program printf("Program running...\n"); return 0; }
In this example:
- If DEBUG_MODE is defined (as it is with #define DEBUG_MODE), the program will compile and run the code inside the #ifdef
- DEBUG_MODE block. This block includes a print statement indicating that debug mode is enabled.
- If DEBUG_MODE is not defined (if you comment out or remove the line #define DEBUG_MODE), the code inside the #else block will be compiled and executed instead, indicating the program is running in normal mode.
- The #endif marks the end of the conditional compilation block.
#ifndef Conditional Compilation Directive Example in C
The #ifndef directive in C is a preprocessor command that checks if a macro is not defined. It stands for “if not defined.” If the specified macro is not defined, the code following the #ifndef up to the corresponding #endif (or an #else, if present) is included in the compilation process. This is often used to prevent double inclusion of header files or to include code conditionally.
Here’s an example demonstrating the use of #ifndef: In this example, we’ll create a simple header file and use #ifndef to ensure that it’s only included once in the compilation process.
my_header.h:
// Check if MY_HEADER_H is not defined #ifndef MY_HEADER_H #define MY_HEADER_H // Contents of the header file void printHello() { printf("Hello, world!\n"); } // End of the conditional #endif
main.c:
#include <stdio.h> #include "my_header.h" #include "my_header.h" // Including the header file again int main() { printHello(); // Function from my_header.h return 0; }
In my_header.h, the #ifndef directive checks if MY_HEADER_H is not defined. If it’s not defined (which is true the first time the header is included), it defines MY_HEADER_H and includes the contents of the header file. The next time this header file is included, MY_HEADER_H will already be defined, so the contents of the header file will be skipped, preventing multiple definitions of the printHello function.
#else Conditional Compilation Directive Example in C
The #else directive in C is used in conjunction with #if (or #ifdef and #ifndef) for conditional compilation. It provides a way to include certain parts of code when the condition specified in the preceding #if (or #ifdef/#ifndef) is false. If the condition is true, the code block following the #if is compiled, and the block following #else is skipped; if the condition is false, the reverse happens. Here’s an example to illustrate the use of #else:
#include <stdio.h> #define DEBUG_MODE 0 int main() { #if DEBUG_MODE printf("Debug mode is ON.\n"); // Additional debug-specific code can be added here. #else printf("Debug mode is OFF.\n"); // Code to execute when debug mode is not enabled. #endif // Rest of the program... return 0; }
In this example:
- The macro DEBUG_MODE is defined with a value of 0.
- The #if DEBUG_MODE checks whether DEBUG_MODE is non-zero (true). Since DEBUG_MODE is 0, the condition is false.
- Therefore, the code block following #if DEBUG_MODE is skipped, and the code block following #else is compiled. This results in “Debug mode is OFF.” being printed.
- The #endif marks the end of the conditional block.
This #else directive is very useful for creating code that behaves differently under different compile-time conditions, such as for debugging versus production builds, for different operating systems, or different versions of a library or API.
#elif Conditional Compilation Directive Example in C
The #elif directive in C is part of conditional compilation, allowing you to define multiple conditional branches in your code. It stands for “else if” and is used in conjunction with #if, #ifdef, #ifndef, and #else directives to create complex conditional compilation scenarios. Here’s an example to demonstrate how #elif is used:
#include <stdio.h> // Define macros to represent different environments #define LINUX // #define WINDOWS // #define MACOS int main() { printf("Starting program...\n"); // Conditional compilation based on the defined macro #ifdef WINDOWS printf("Running on Windows.\n"); // Windows-specific code goes here #elif defined(LINUX) printf("Running on Linux.\n"); // Linux-specific code goes here #elif defined(MACOS) printf("Running on macOS.\n"); // macOS-specific code goes here #else printf("Unknown Operating System.\n"); #endif // Rest of the program printf("Program running...\n"); return 0; }
In this example:
- The #ifdef WINDOWS block will compile if WINDOWS is defined.
- If WINDOWS is not defined, but LINUX is defined (#elif defined(LINUX)), then the Linux-specific code block will compile.
- Similarly, the macOS-specific code block will compile if MACOS is defined (#elif defined(MACOS)).
- If none of these macros are defined, the #else block will compile, indicating an unknown operating system.
The #elif directive allows for more nuanced control and helps write more readable code for scenarios involving multiple conditions. It’s particularly useful in projects that need to be compiled in different environments with specific configurations for each.
#endif Conditional Compilation Directive Example in C
The #endif directive in C is used in conjunction with conditional compilation directives like #if, #ifdef, and #ifndef. It marks the end of a conditional directive block. These directives are part of the C preprocessor, which processes directives before the actual compilation of the code starts.
Here’s an example that demonstrates the use of #endif in a conditional compilation block: Suppose we have a program where we want to execute different blocks of code based on whether a macro is defined or not. We can use #if, #else, and #endif to achieve this.
#include <stdio.h> // Define a macro for demonstration purposes #define FEATURE_ENABLED int main() { // Conditional compilation based on whether FEATURE_ENABLED is defined #ifdef FEATURE_ENABLED printf("Feature is enabled!\n"); #else printf("Feature is not enabled.\n"); #endif // End of the conditional block return 0; }
In this example:
- #ifdef FEATURE_ENABLED checks if FEATURE_ENABLED is defined.
- If it is, the code inside the #ifdef block (printf(“Feature is enabled!\n”);) is compiled.
- If FEATURE_ENABLED is not defined, the compiler moves to the #else block and compiles that code instead.
- #endif marks the end of this conditional compilation block.
This kind of conditional compilation is useful for creating code that behaves differently based on certain compile-time conditions, such as whether a feature is enabled, which platform the code is being compiled for, or for debugging purposes.
#define Conditional Compilation Directive Example in C
The #define directive in C is a preprocessor command used to define a macro. This macro can then be used to control conditional compilation with directives like #if, #ifdef, and #ifndef. When the preprocessor encounters a macro, it replaces it with its corresponding value or code throughout the program before the compilation process begins. Here’s an example demonstrating the use of #define:
#include <stdio.h> #define PI 3.14159 #define PRINT_AREA(radius) printf("Area of circle: %f\n", PI * (radius) * (radius)) int main() { float radius = 5.0; // Using the defined macro PI printf("Value of PI: %f\n", PI); // Using the defined macro PRINT_AREA PRINT_AREA(radius); return 0; }
In this example:
- PI is defined as a macro with the value 3.14159.
- PRINT_AREA is a macro function that takes an argument radius and prints the area of a circle using the PI macro.
- In main, PI is used directly in a printf statement to print its value.
- PRINT_AREA is used with the argument radius to calculate and print the area of a circle.
This shows how #define can be used to create constants and macro functions, simplifying code and making it more readable and maintainable. Moreover, since these are preprocessor directives, the replacement is done before the actual compilation, making the process efficient.
#undef Conditional Compilation Directive Example in C
The #undef directive in C is used to undefine a previously defined macro. This can be particularly useful in scenarios where you want to temporarily change the definition of a macro within a file or to ensure that a macro is not defined at a certain point in the code. Here’s an example to illustrate the use of #undef:
#include <stdio.h> // Define a macro initially #define FEATURE_ENABLED int main() { // Check if the macro is defined #ifdef FEATURE_ENABLED printf("Feature is initially enabled.\n"); #else printf("Feature is initially disabled.\n"); #endif // Undefine the macro #undef FEATURE_ENABLED // Check again if the macro is defined #ifdef FEATURE_ENABLED printf("Feature is still enabled.\n"); #else printf("Feature is now disabled.\n"); #endif return 0; }
In this code:
- Initially, FEATURE_ENABLED is defined using #define FEATURE_ENABLED.
- The first #ifdef FEATURE_ENABLED block checks if FEATURE_ENABLED is defined. Since it is, “Feature is initially enabled.” is printed.
- The macro is then undefined with #undef FEATURE_ENABLED.
- After undefining, the second #ifdef FEATURE_ENABLED block checks again if FEATURE_ENABLED is defined. Since it’s undefined, “Feature is now disabled.” is printed.
The #undef directive is often used in complex projects where conditional compilation is required based on changing requirements or to avoid conflicts with macros defined in other included files.
In the next article, I will discuss Miscellaneous Directives in C language. In this article, I try to explain Conditional Compilation Directives in C. I hope you enjoy this Conditional Compilation Directive in C article. I would like to have your feedback. Please post your feedback, questions, or comments about this article.