Let’s first take a look at the following piece of code. What do you think the output will be?
#include <stdio.h>
#define add(x) x + x
int main(){
int ret = add(2) * 10;
printf("%d", ret);
return 0;
}
To understand the output of this program, we must discuss macros.This is the official explanation of macros; interested readers can check it out (https://en.cppreference.com/w/c/preprocessor/replace)
In fact, macros in C are a type of preprocessor directive, so to understand what a macro is, we must first talk about what preprocessing is.
The C/C++ files we write are not directly transformed into executable programs in one step; they go through several stages, each with its own responsibilities. If any step fails, it will inevitably lead to the inability to generate the corresponding executable program.
The first step is what we call preprocessing.
During the preprocessing stage, the main task is to process the directives in the code that start with the # symbol
Among these, the directives that start with #define are what we refer to as macros.
The work done by macros can be summarized in one sentence: text replacement.
Let’s look at the following piece of code:
#include <stdio.h>
#define NUM 10];
int main(){
int arr[NUM];
return 0;
}
For this code, if you only look at the part inside the main function, you would definitely think it won’t compile. However, do not overlook the line #define NUM 10];
As we just mentioned, the directives that start with #define are called macros, and the work of a macro is text replacement. In simple terms, #define NUM 10]; means that NUM in the code will be replaced with 10];
In other words, after preprocessing, the main function will become:
int main(){
int arr[NUM];
return 0;
}
In summary: #define XXX YYY means to replace XXX with YYY.
Therefore, when we use macro-defined constants, we see a syntax rule that states we cannot add a semicolon after it.
#define NUM 10;
int main(){
int arr[NUM];
return 0;
}
Now, from the essence of macros, the reason we cannot add a semicolon is that adding a semicolon would change int arr[NUM]; to int arr[10;];
Which would lead to a syntax error!
Now, let’s return to the question posed at the beginning: what is the output of the following code?
#include <stdio.h>
#define add(x) x + x
int main(){
int ret = add(2) * 10;
printf("%d", ret);
return 0;
}
Based on the previous conclusions, we know that add(x) will be replaced with x + x.
Notice that add(x) looks very much like a function call
And x + x resembles the function body
For this type of macro, we call it a macro function.
The replacement of macro functions is essentially parameterized text replacement
What we mean by parameterized text replacement can be summarized in one sentence: parameter replacement, with the rest unchanged.
To understand this statement, we must first agree that the parameters of macro functions are similar to the parameters of functions we have learned (note that these are function parameters, not functions).
During replacement, all formal parameters in the macro definition are found and replaced directly with the actual parameters passed during the call, while the other parts remain unchanged.
For example, in add(2), according to the above statement, it will be transformed into 2 + 2.
Thus:
int ret = add(2) * 10; will transform into int ret = 2 + 2 * 10;
Therefore, the correct output should be 22
However, many beginners might think the output is 40.
The reason is that they treat macro functions as real functions, meaning they think the return value of 2 + 2 is obtained and then multiplied by 10, which is actually incorrect!
The operation performed by macro functions is called replacement, and it does not create a function stack frame for calling!
Please remember: macro functions are simply text replacements and do not automatically add parentheses!
If you have any interesting content, feel free to leave a message or send a private message.