1.6 KiB
| tags | |
|---|---|
|
Think of macros as a find and replace that takes place before compilation at the pre-processor stage.
They are ephemeral and never make it into the compiled code in the form they are defined as.
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.
Starting with a simple example:
#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_CAPSto 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:
int square(int x) { return x * x; }
int a = square(5);
Can be reduced to a macro:
#define SQUARE(x) ((x) * (x))
int a = SQUARE(5);
Which, because it uses # is processed at the
pre-processor compilation stage, becomes:
int a = ((5) * (5));
after pre-processing but before compilation.