In C and C + + languages, an identifier is allowed to represent a string, called a macro, which can be a constant, an expression, a string of formatting, and so on. When compiling preprocessing, all occurrences of the "macro name" in the program are substituted with the string in the macro definition, which is called "macro substitution" or "macro expansion." A macro definition is done by a macro definition command in the source program. Macro substitution is done automatically by the preprocessor. If the string is an expression, what we call a functional macro definition, what is the difference between a functional macro definition and a normal function?
Let's use the following two lines of code as an example to expand the description:
Functional macro Definition: #define MAX (A,b) ((a) > (b)? ( A):(B))
normal function: MAX (a,b) {return a>b?a:b}
(1) Function macro-defined parameters have no type, the preprocessor is only responsible for formal substitution, and not for parameter type checking, so be careful when passing parameters.
(2) The code that invokes the true function differs from the instructions generated by the code compiled by the calling function macro definition.
If Max is a normal function, then its function body return a > B? A:B; To compile the build instructions, each call that appears in the code is compiled to generate the command for the arguments and calls. If Max is a functional macro definition, the macro definition itself does not have to compile the build instructions, but the instructions that appear in the code each time the compilation is generated are equivalent to a function body, rather than a few simple parameters and call instructions. Therefore, using a functional macro definition to compile a generated target file is larger.
(3) Functional macro definitions should pay attention to formatting, especially parentheses.
If the above function macro definition is written #define MAX (A, B) (A>B?A:B), omitting the inner brackets, the macro expansion becomes k = (i&0x0f>j&0x0f?i&0x0f:j&0x0f), The priority of the operation is wrong. In the same way, the outer brackets of this macro definition cannot be saved. If the function is to replace the macro with ++max (A,B), the macro expansion becomes + + (a) > (b)? (a):(B), the operation priority is also wrong.
(4) If the function argument is an expression, the invocation of a normal function is not the same as the replacement process of a function macro definition.
The value of the argument expression is then passed to the formal parameter, and if the argument expression has side Effect, then these sideeffect occur only once. For example, Max (++a, ++b), if Max is a normal function, A and B only add one time. But if the MAX function macro is defined, expand to K = ((++a) > (++b)? ( ++A):(++b)), A and B are not necessarily added once or twice. So if the argument is an expression, be sure to look carefully when replacing the functional macro definition.
(5) Functional macro definitions often result in lower code execution efficiency.
Look at the following code:
Copy Code code as follows:
int a[]={9,3,5,2,1,0,8,7,6,4};
int Max (n)
{
Return N==0?a[0]:max (A[n],max (n-1));
}
int main ()
{
Max (9);
return 0;
}
If the normal function, then by recursion, the desirable maximum value, time complexity of O (n). However, if a function macro is defined, the macro expands to (A[n]>max (n-1) A[n]:max (n-1), where Max (n-1) is called two times, so that the time complexity can be high by recursion.
Although functional macro definitions have many drawbacks than normal functions, however, as long as careful use or will significantly improve the execution efficiency of the code, after all, eliminating the allocation and release of stack frames, parameters, return values, such as a series of work, so those short and frequently called functions often use functional macro definition to replace the implementation.