2025-12-17 18:22:42 +00:00
|
|
|
---
|
|
|
|
|
tags:
|
|
|
|
|
- C
|
|
|
|
|
---
|
|
|
|
|
|
2026-02-08 19:22:03 +00:00
|
|
|
Think of macros as a find and replace that takes place before compilation at the
|
|
|
|
|
[pre-processor](./C_compilation_process.md) stage.
|
2025-12-17 18:22:42 +00:00
|
|
|
|
2026-02-08 19:22:03 +00:00
|
|
|
They are ephemeral and never make it into the compiled code in the form they are
|
|
|
|
|
defined as.
|
2025-12-17 18:22:42 +00:00
|
|
|
|
2026-02-08 19:22:03 +00:00
|
|
|
When the preprocessor injects the value, the injection happens "inline" without
|
|
|
|
|
having to call functions which make costly alterations to the stack, which is
|
|
|
|
|
the main benefit - efficiency.
|
2025-12-17 18:22:42 +00:00
|
|
|
|
2026-02-08 19:22:03 +00:00
|
|
|
Starting with a simple example:
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
#define NAME "Thomas"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This is not actually a variable because it has no memory address. It never makes
|
|
|
|
|
it to memory-assignation because it doesn't exist after pre-processing. By the
|
|
|
|
|
compilation stage,j this value has been added to the code as a type
|
|
|
|
|
corresponding to the literal you defined; in this case a string literal
|
|
|
|
|
(`char *`). To emphasise, the macro itself has no type because it doesn't exist
|
|
|
|
|
at the type level (compilation), the data type it represents after injection is
|
|
|
|
|
applied by the compiler through parsing.
|
|
|
|
|
|
|
|
|
|
> The convention is to have macros in `ALL_CAPS` to distinguish them from real
|
|
|
|
|
> variables. Don't confuse them for constants, constants are actually written in
|
|
|
|
|
> lowercase like other actual variables.
|
|
|
|
|
|
|
|
|
|
To use a more complex example, a function and function call such as:
|
2025-12-17 18:22:42 +00:00
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
int square(int x) { return x * x; }
|
|
|
|
|
int a = square(5);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Can be reduced to a macro:
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
#define SQUARE(x) ((x) * (x))
|
|
|
|
|
int a = SQUARE(5);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Which, because it uses `#` is processed at the
|
|
|
|
|
[pre-processor compilation stage](./C_compilation_process.md), becomes:
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
int a = ((5) * (5));
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
after pre-processing but before compilation.
|