Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Learn Core Directives | Conditional compilation
C Preprocessing
course content

Course Content

C Preprocessing

C Preprocessing

1. Introduction to Preprocessing
2. Macros
3. Conditional compilation

book
Core Directives

c

main

copy
12345678910
#include <stdio.h> #define VERSION 2 int main() { #if VERSION == 2 // If VERSION equals 2, this block will be compiled printf("Version 2 is active\n"); #endif return 0; }

Use it when:

  • To include or exclude a code block based on a compile-time constan;
  • To create multiple versions of a program depending on platform, version, or configuration.

Why it’s useful:

  • Eliminates code from the compiled binary entirely;
  • Useful for portable code: e.g., different behavior for Windows/Linux;
  • Helps enable/disable debugging or logging code.
c

main

copy
1234567891011
#include <stdio.h> #define VERSION 1 int main() { #if VERSION == 2 printf("Version 2 is active\n"); #elif VERSION == 1 printf("Version 1 is active\n"); #endif return 0; }

Use it when:

  • You have multiple exclusive compile-time conditions and want to select one;
  • You want to avoid nested #if...#else blocks.

Why it’s useful:

  • Keeps configuration logic clean and readable;
  • Avoids writing deep nesting with many #if.
c

main

copy
12345678910111213
#include <stdio.h> #define VERSION 5 int main() { #if VERSION == 1 printf("Version 1\n"); #elif VERSION == 2 printf("Version 2\n"); #else printf("Unknown version\n"); #endif return 0; }

Use it when:

  • You want to define a default code path if all previous #if or #elif conditions fail;
  • Helps ensure one and only one block of code gets compiled.

Why it’s useful:

  • Guarantees fallbacks are defined;
  • Makes it easy to handle cases like β€œif debugging is disabled”.

Use it when:

  • You started a conditional compilation block β€” it's mandatory to close it.

Why it’s useful:

  • Keeps the preprocessor logic valid; -Allows clear structure and grouping.

Let's rewrite the example from the previous section where we implemented logging. Back then, we used the switch...case statement.

Task

Swipe to start coding

Tasks:

  1. To handle each level of logging, use the required conditional compilation directive;
  2. To handle each level of logging, use the required conditional compilation end directive.

Solution

Switch to desktopSwitch to desktop for real-world practiceContinue from where you are using one of the options below
Everything was clear?

How can we improve it?

Thanks for your feedback!

SectionΒ 3. ChapterΒ 2
toggle bottom row

book
Core Directives

c

main

copy
12345678910
#include <stdio.h> #define VERSION 2 int main() { #if VERSION == 2 // If VERSION equals 2, this block will be compiled printf("Version 2 is active\n"); #endif return 0; }

Use it when:

  • To include or exclude a code block based on a compile-time constan;
  • To create multiple versions of a program depending on platform, version, or configuration.

Why it’s useful:

  • Eliminates code from the compiled binary entirely;
  • Useful for portable code: e.g., different behavior for Windows/Linux;
  • Helps enable/disable debugging or logging code.
c

main

copy
1234567891011
#include <stdio.h> #define VERSION 1 int main() { #if VERSION == 2 printf("Version 2 is active\n"); #elif VERSION == 1 printf("Version 1 is active\n"); #endif return 0; }

Use it when:

  • You have multiple exclusive compile-time conditions and want to select one;
  • You want to avoid nested #if...#else blocks.

Why it’s useful:

  • Keeps configuration logic clean and readable;
  • Avoids writing deep nesting with many #if.
c

main

copy
12345678910111213
#include <stdio.h> #define VERSION 5 int main() { #if VERSION == 1 printf("Version 1\n"); #elif VERSION == 2 printf("Version 2\n"); #else printf("Unknown version\n"); #endif return 0; }

Use it when:

  • You want to define a default code path if all previous #if or #elif conditions fail;
  • Helps ensure one and only one block of code gets compiled.

Why it’s useful:

  • Guarantees fallbacks are defined;
  • Makes it easy to handle cases like β€œif debugging is disabled”.

Use it when:

  • You started a conditional compilation block β€” it's mandatory to close it.

Why it’s useful:

  • Keeps the preprocessor logic valid; -Allows clear structure and grouping.

Let's rewrite the example from the previous section where we implemented logging. Back then, we used the switch...case statement.

Task

Swipe to start coding

Tasks:

  1. To handle each level of logging, use the required conditional compilation directive;
  2. To handle each level of logging, use the required conditional compilation end directive.

Solution

Switch to desktopSwitch to desktop for real-world practiceContinue from where you are using one of the options below
Everything was clear?

How can we improve it?

Thanks for your feedback!

SectionΒ 3. ChapterΒ 2
Switch to desktopSwitch to desktop for real-world practiceContinue from where you are using one of the options below
We're sorry to hear that something went wrong. What happened?
some-alt