0Pricing
C Academy · Lesson

Conditional Compilation

ifdef and macros.

Conditional Compilation is a free C Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

The Preprocessor

Before the compiler ever sees your code, the preprocessor runs. It handles every line starting with #: includes, macros, and conditionals.

Conditional compilation lets you include or exclude blocks of code based on conditions evaluated at this stage, producing different builds from one source.

Defining Macros

#define creates a macro. With no value it is just a flag you can test later.

Object-like macros replace a name with text; flags simply mark that something is set.

#define MAX_USERS 100   /* value macro */
#define DEBUG          /* flag macro */

ifdef and ifndef

#ifdef NAME keeps the block only if NAME is defined. #ifndef keeps it only if NAME is not defined.

Here the debug print exists only in debug builds. Without DEBUG defined, the compiler never even sees that line.

#include <stdio.h>
#define DEBUG

int main(void) {
#ifdef DEBUG
    printf("debug: starting\n");
#endif
    printf("running\n");
    return 0;
}

if, elif, else

#if evaluates a constant integer expression. Combine with #elif and #else for multi-way selection.

This picks code based on a version number macro.

#include <stdio.h>
#define VERSION 2

int main(void) {
#if VERSION >= 2
    printf("new feature on\n");
#else
    printf("legacy mode\n");
#endif
    return 0;
}

The defined Operator

Inside #if you can test definition with defined(NAME), and combine tests with && and ||.

This is more flexible than #ifdef, which can only test one name.

#if defined(LINUX) && !defined(EMBEDDED)
    /* desktop Linux code */
#endif

Defining At Compile Time

You do not have to hardcode macros. The -D flag defines them on the command line.

This is how build systems switch features without editing source. -DDEBUG is the same as #define DEBUG at the top of every file.

gcc -DDEBUG -DVERSION=3 -o app app.c

Platform Detection

Compilers predefine macros describing the target. You use them to write portable code.

  • _WIN32 — Windows (32 or 64 bit)
  • __linux__ — Linux
  • __APPLE__ — macOS / iOS

Branch on these to call the right platform API.

#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif

Header Include Guards

The classic use of conditionals is the include guard, which stops a header from being processed twice.

The first include defines the guard macro; subsequent includes skip the body because the macro is already defined.

#ifndef UTILS_H
#define UTILS_H

int add(int a, int b);

#endif /* UTILS_H */

Commenting Out Code

#if 0 ... #endif reliably disables a block, even one that already contains comments.

Unlike /* */, it nests safely, so it is the standard way to temporarily exclude code during debugging.

#if 0
    legacy_function();   /* disabled for now */
    /* with internal comments too */
#endif

Inspecting Preprocessor Output

To see exactly what the compiler will compile, run only the preprocessor with -E.

This expands all includes, macros, and conditionals, which is invaluable when a macro misbehaves.

gcc -E app.c | less

Feature Toggles In Practice

A common pattern is a single config header that turns features on or off for the whole project.

Flip one #define and every guarded block across all files responds. This keeps optional features cleanly separated from the core code.

#include <stdio.h>
#define FEATURE_LOGGING 1

int main(void) {
#if FEATURE_LOGGING
    printf("logging enabled\n");
#endif
    printf("app ready\n");
    return 0;
}

Quick Check

Predict the behavior of a command-line define.

Recap

You now control conditional compilation:

  • #ifdef/#ifndef test whether a macro is defined
  • #if/#elif/#else evaluate constant expressions, with defined()
  • -DNAME defines macros from the command line for feature switching
  • Predefined platform macros enable portable code; include guards prevent double inclusion

Next: organizing code across multiple files.

Frequently asked questions

Is the “Conditional Compilation” lesson free?

Yes — the full text of “Conditional Compilation” is free to read here on the web, and the C Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C Academy course, upgrade to CoddyKit PRO.

What will I learn in “Conditional Compilation”?

ifdef and macros. You practise C Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C Academy?

No prior experience is required. C Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Conditional Compilation” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C Academy lesson?

Yes. Every C Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Conditional Compilation
  2. Multi-File Projects
  3. Makefiles
  4. Static and Shared Libraries
← Back to C Academy