Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🔵 Core C++  ·  Lesson 34

Preprocessor Directives in C++

In this lesson: C++ preprocessor directives — #include, #define, #ifdef, #ifndef, #pragma — with examples. In Hindi & English.

What is the preprocessor?

Before the compiler sees your code, a program called the preprocessor reads it and follows every line that starts with #. It copies header files in, replaces macro names with their text, and removes blocks of code you have turned off. The result is plain C++ that the compiler then translates.

Directives are instructions to the preprocessor, not C++ statements. They start with #, occupy one line, and do not end with a semicolon.

Directives at a glance

DirectivePurpose
#includeInsert the contents of another file
#defineDefine a macro (a name replaced by text)
#undefRemove a macro definition
#if, #elif, #else, #endifKeep or skip code based on a condition
#ifdef, #ifndefKeep code only if a macro is (not) defined
#errorStop compilation with a message
#pragmaCompiler-specific instruction, e.g. #pragma once
#lineChange reported line numbers (rare)

#include

C++
#include <iostream>     // standard header
#include "marks.h"      // your own header

See header files for the difference between < > and " " and how include guards work.

#define: object-like macros

C++
#include <iostream>
#define SCHOOL "Alpine Public School"
#define MAX_STUDENTS 40

int main() {
    std::cout << SCHOOL << " allows " << MAX_STUDENTS << " students per class.\n";
    return 0;
}
Alpine Public School allows 40 students per class.

Every MAX_STUDENTS is replaced by 40 before compilation. In C++ a constexpr constant is usually better because it has a type — see constants and literals.

Function-like macros and their traps

C++
#define SQUARE(x) x * x
int a = SQUARE(3 + 1);   // becomes 3 + 1 * 3 + 1  ->  7, not 16!

Always wrap the parameter and the whole body in parentheses:

C++
#define SQUARE(x) ((x) * (x))

Even then, SQUARE(i++) increments i twice. A constexpr function has none of these problems:

C++
constexpr int square(int x) { return x * x; }

Conditional compilation

Code between #if/#ifdef and #endif is compiled only when the condition is true. A common use is debug output you can switch off in one place:

C++
#include <iostream>
#define DEBUG 1

int main() {
    int total = 0;
    for (int m : {78, 85, 69}) {
        total += m;
#if DEBUG
        std::cout << "[debug] added " << m << ", total = " << total << "\n";
#endif
    }
    std::cout << "Total: " << total << "\n";
    return 0;
}
[debug] added 78, total = 78 [debug] added 85, total = 163 [debug] added 69, total = 232 Total: 232

Change DEBUG to 0 and the debug lines disappear from the compiled program entirely. You can also define a macro from the command line: g++ -DDEBUG=1 main.cpp.

Platform-specific code uses predefined macros:

C++
#ifdef _WIN32
    system("cls");
#else
    system("clear");
#endif

#ifndef include guards and #pragma once

C++
#ifndef MARKS_H
#define MARKS_H
// ... declarations ...
#endif

The first time the header is included MARKS_H is not defined, so the content is used and MARKS_H gets defined. Any later include skips it. #pragma once does the same job in one line on all major compilers.

#undef and #error

C++
#define LIMIT 10
#undef LIMIT          // LIMIT no longer exists

#if __cplusplus < 201703L
#error "This program needs C++17 or newer"
#endif

#error is useful to stop a build early with a clear message instead of confusing errors later.

Predefined macros

MacroValue
__LINE__Current line number
__FILE__Current file name
__DATE__, __TIME__Date and time of compilation
__cplusplusC++ standard version, e.g. 201703L for C++17
C++
std::cout << "Compiled on " << __DATE__ << " (line " << __LINE__ << ")\n";

Common mistakes

  • Adding a semicolon to a #define (#define MAX 100;).
  • Missing parentheses in function-like macros.
  • Forgetting #endif, which gives "unterminated #if" errors.
  • Using macros where constexpr, inline functions or templates are clearer and type-safe.
  • Spaces between the macro name and (: #define SQ (x) ((x)*(x)) defines an object-like macro, not a function-like one.
🏋️ Practice

Write a program with a DEBUG switch that prints each step of a factorial loop only when DEBUG is 1. Then compile it once with -DDEBUG=0 and once with -DDEBUG=1 (remove the #define from the file) and compare the output.

Summary

  • The preprocessor runs before compilation and handles lines starting with #.
  • #include inserts files; #define creates text-replacement macros.
  • #if/#ifdef/#ifndef ... #endif keep or drop code — used for debug code, platforms and include guards.
  • Directives never end with a semicolon.
  • Prefer constexpr and inline functions over macros in C++.

Related: header files, inline functions, constants and literals.

Frequently Asked Questions

What is a preprocessor directive in C++?
A preprocessor directive is a line starting with # that is processed before compilation. The preprocessor uses these lines to include files, replace macro names with text, and keep or remove blocks of code. The compiler then sees only the resulting text.
What is the difference between a macro and a function in C++?
A macro is expanded as text by the preprocessor, so it has no type checking and its arguments may be evaluated more than once. A function is compiled code with typed parameters that are evaluated exactly once. In modern C++ prefer constexpr or inline functions over function-like macros.
What is conditional compilation?
Conditional compilation uses #if, #ifdef, #ifndef, #elif, #else and #endif to include or skip code before compiling. It is used for include guards, debug-only code, and code that differs between Windows and Linux.
Does a preprocessor directive end with a semicolon?
No. A directive ends at the end of the line. Writing #define MAX 100; puts the semicolon into the replacement text, so int a[MAX]; becomes int a[100;]; and fails to compile.
← Back to C++ Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.
Next topicCommand Line Arguments Your progress: 34 / 81 (42%) · Lesson 35 / 81 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free