100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

C Preprocessor Macros Cheat Sheet

C Preprocessor Macros Cheat Sheet

Details the C preprocessor: object-like and function-like macros, conditional compilation, include guards, and stringizing and token-pasting operators.

2 PagesIntermediateApr 15, 2026

Object-like and Function-like Macros

Text substitution performed before compilation.

c
#define PI 3.14159265358979         // Object-like macro (constant)#define MAX(a, b) ((a) > (b) ? (a) : (b))   // Function-like macro#define SQUARE(x) ((x) * (x))       // Always parenthesize params and resultdouble area = PI * SQUARE(5);       // Expands safely thanks to the parensint m = MAX(3, 7);                  // Expands to ((3) > (7) ? (3) : (7))

Conditional Compilation

Include or exclude code based on compile-time conditions.

c
#define DEBUG 1#if DEBUG    #define LOG(msg) printf("[DEBUG] %s\n", msg)#else    #define LOG(msg)#endif#ifndef HEADER_H#define HEADER_H// header contents go here (include guard)#endif#ifdef _WIN32    // Windows-specific code#elif defined(__linux__)    // Linux-specific code#endif

Stringizing and Token Pasting

The # and ## preprocessor operators.

c
#define STRINGIFY(x) #x              // Turns an argument into a string literal#define CONCAT(a, b) a##b            // Pastes two tokens togetherprintf("%s\n", STRINGIFY(hello));    // Prints: helloint CONCAT(var, 1) = 10;             // Expands to: int var1 = 10;#define VERSION_MAJOR 1#define VERSION_MINOR 2// Adjacent string literals concatenate at compile timeconst char *ver = STRINGIFY(VERSION_MAJOR) "." STRINGIFY(VERSION_MINOR);

Pitfalls & Good Practices

Rules of thumb for writing safe macros.

  • Parenthesize everything- Wrap macro parameters and the whole expansion in parens to avoid operator-precedence bugs
  • No side effects- MAX(i++, j) evaluates an argument twice — avoid expressions with side effects in macro args
  • Macros vs functions- Macros are text substitution at compile time: no type checking and no function call overhead
  • Include guards- #ifndef / #define / #endif prevents a header from being included more than once per translation unit
  • #pragma once- A non-standard but widely supported alternative to manual include guards
  • Line continuation- A trailing backslash (\) continues a #define across multiple lines
  • Variadic macros- #define LOG(fmt, ...) printf(fmt, __VA_ARGS__) accepts a variable argument list (C99)
Pro Tip

Wrap multi-statement macros in a do { ... } while(0) block so they act like a single statement and don't silently break when used inside an unbraced if/else.

Was this cheat sheet helpful?

Explore Topics

#CPreprocessorMacros#CPreprocessorMacrosCheatSheet#Programming#Intermediate#Object#Like#Function#Macros#OOP#Functions#CheatSheet#SkillVeris