SyntaxStudy
Sign Up
C #define, #include, and Object-Like Macros
C Beginner 1 min read

#define, #include, and Object-Like Macros

The C preprocessor runs before the compiler and performs textual transformations on the source file. The three most common directives are `#include`, `#define`, and the conditional compilation directives. `#include
` inserts the content of a system header; `#include "header"` inserts a local header. This is how function prototypes and type definitions from library headers reach your code. Object-like macros defined with `#define NAME value` replace every occurrence of `NAME` in subsequent source text with `value` before compilation. They are commonly used for named constants (like `#define MAX_BUFFER 1024`), versioning strings, and configuration flags. Unlike `const` variables, macros have no type and no scope — they are pure textual substitution. This can lead to surprises when the "value" contains operators: always use parentheses around complex macro values. Header guards prevent a header file from being included more than once in a single translation unit, which would cause duplicate type and function declarations. The classic pattern uses `#ifndef`, `#define`, and `#endif` to wrap the entire header. The modern alternative is `#pragma once`, a non-standard but nearly universally supported directive that achieves the same goal in a single line.
Example
/*
 * config.h — demonstrates header guard and object-like macros
 */
#ifndef CONFIG_H
#define CONFIG_H

/* Version information */
#define VERSION_MAJOR 2
#define VERSION_MINOR 5
#define VERSION_PATCH 1
#define VERSION_STR   "2.5.1"

/* Buffer sizes */
#define MAX_PATH_LEN  260
#define MAX_LINE_LEN  1024
#define MAX_USERS     512

/* Computed macro — parentheses prevent operator-precedence bugs */
#define KB(n)  ((n) * 1024)
#define MB(n)  (KB(n) * 1024)

#endif /* CONFIG_H */